Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

DevでもPowerShellを活用しよう!

2,979 views

Published on

第 4 回 PowerShell 勉強会
http://jpposh.doorkeeper.jp/events/14261

の発表資料です。

Published in: Technology
  • Be the first to comment

DevでもPowerShellを活用しよう!

  1. 1. DevでもPowerShellを活用しよう! PowerShell勉強会#4 2014/10/11 @oota_ken
  2. 2. アジェンダ 本セッションの目的 本セッションの対象者 本セッションの形式 キーバインドカスタマイズ シェルで計算機 ファイル処理 文字列処理 開発ツール PowerShell固有 タブ補完
  3. 3. 自己紹介 仕事 (Test) Automator 関西弁分からない埼玉生まれ だけど、先月まで明石でビルドの自動化 テストその他を自動化するエンジニア GUIが苦手だけど、最近はGUIのテストの自 動化が多い 仕事上ではMac Bash, Groovy, Gradle, IntelliJ IDEA 自転車ツーキニスト こちらが本職 にしたい 好きな技術 理論体系 SQL 関係代数 シンプル シェル パイプライン 型付け+ ストリーム Windows PowerShell(*⌒▽⌒*) REPL 最初のコンピュータがREPL ぴゅう太G-BASIC PC-8801mkII N88-BASIC
  4. 4. 本セッションの目的 Windows PowerShellに対する世間の認識とMicrosoftのメッセージ IT Adminの自動化ツール DevはVisual Studio ITエンジニアの人数構成比(主観) Dev >>> IT Admin Windowsで上で開発しているけどNot Visual Studio, but editor and shell Cygwin ? Git BASH ? cmd.exe ?
  5. 5. 本セッションの対象者 Windows上でエディタとCLIベースで開発しているDev UNIXのシェルが好きでCygwinやMinGWを使っているDev 使いにくいなーと思いつつ、コマンドプロンプトを使っているDev Windows PowerShellってあるけど、起動したことないDev
  6. 6. 本セッションの形式 同じ問題をCygwin(bash), cmd.exe, PowerShellの3つで解いてみる 問題 シェルで計算機 ヘルプ ファイル処理 文字列処理 開発ツール PowerShell固有 タブ補完 UNIXエンジニア向けにCygwin(主にbash)から解説する より、PowerShellらしい書き方を追求してみる PowerShellを使った方が嬉しい状況を探ってみる
  7. 7. キーバンドカスタマイズ Cygwinからの移行を阻むもの コマンドレット Set-Aliasで最低限はなんとかなる キーバインド PowerShell自体にはキーバインドを変更する機能がない Ctrl-p, Ctrl-n, Ctrl-a, Ctrl-eとかないと無理 AutoHotkey ウィンドウ毎のキーバインドやマクロを定義できる汎用ツール PowerShellのキーバインドをカスタマイズすると副次的にcmd.exeもカスタマイズされるので便利
  8. 8. AutoHotKey 最低限のbashライクのキーバインド #IfWinActive, ahk_class ConsoleWindowClass ^a::SendInput {HOME} ^e::SendInput {END} ^u::SendInput {ESC} ^p::SendInput {Up} ^n::SendInput {Down} ^l::SendInput {ESC}cls{ENTER} ^k::SendInput {F4} ^f::SendInput {right} ^b::SendInput {left} #IfWinActive とりあえずストレスはなくなる おまけ WindowsキーでVimを起動 #n:: Run gvim return
  9. 9. シェルで計算機 シェル組み込み外部コマンド(レット) Cygwin(bash) let x=1 x=$((x+2)) x=$(expr $x + 2) echo "x = 1; x += 2; x" | bc cmd.exe set /a x=1 set /a x+=2 PowerShell $x = 1 $x += 2 [math]::cos([mat h]::pi / 3) Cygwin(bash) 空白を入れると、文字列扱いで渡すな どの工夫が必要で日常的に使うには 少々ストレスがある nodeやirb, groovyshを使ってしまうことが 多い cmd.exe 同じく空白問題がある PowerShell 空白を気にしなくて良い 関数電卓としても簡単に利用できる
  10. 10. ヘルプとコマンドを探す シェルヘルプコマンドを探す Cygwin(bash) man コマンド名 コマンド--help which コマンド名 cmd.exe help コマンド名 コマンド名/? where コマンド名 PowerShell Get-Help コマン ドレット名 help コマンドレッ ト名 man コマンドレッ ト名 get-command コマ ンド名 PowerShell 内蔵のヘルプでは、文法しか分からな いので、使い方を知るのが難しい "-Online"オプションをつけて、Tech-Net のオンラインヘルプを表示すると、日本 語かつサンプルまであるので、分かり やすい それらしいコマンドはUNIXやDOSのコマ ンドとしてaliasされているが、オプション はまるでことなるので、きっかけ程度に しかならない
  11. 11. ファイル処理 条件に一致するファイルを列挙する 条件に一致するファイルを検索する ファイルの中身を表示する ファイルの末尾を表示する ファイルの内容を比較する CSVファイルを読み込んで処理する
  12. 12. 条件に一致するファイルを列挙する シェルコマンドalias Cygwin(bash) ls パターン cmd.exe dir パターン PowerShell Get-ChildItem パ ターン Get-ChildItem フォルダ-Filter パターン Get-ChildItem フォルダ- Include パターン -Recurse dir, gci, ls ls ls -alF ls -alF *.exe dir dir *.exe Get-ChildItem Get-ChildItem *.exe Get-ChildItem . -Filter *.exe Get-ChildItem . -Include *.exe -Recurse これは挙動が違う
  13. 13. Get-ChildItemPowerShellっぽく 20KB以上のEXEファイル Get-ChildItem *.exe | Where-Object Length -ge 20KB 最終更新日が2014/01/01のEXEファイル Get-ChildItem *.exe | Where-Object LastWriteTime -ge "2014/01/01" パイプに渡ってくるものがオブジェクトなのでGet-ChildItemのオプションだけでは制 御できないフィルタも簡単に記述できる
  14. 14. 条件に一致するファイルを検索する シェルコマンドalias Cygwin(bash) find フォルダ- name パターン cmd.exe where /R フォル ダパターン PowerShell Get-ChildItem パ ターン-Recurse Get-ChildItem - Filter パターン- Recurse Get-ChildItem フォルダ- Recurse -Include パターン dir, gci, ls ls find . -name "*.exe" dir where /R . *.exe Get-ChildItem Get-ChildItem *.exe -Recurse Get-ChildItem . -Recurse -Include *.exe はまりどころ "-include"は"-Recurse"をつけたときに初め て有効になる
  15. 15. ファイルの中身を表示する シェルコマンドalias Cygwin(bash) cat ファイル cmd.exe type ファイル PowerShell Get-Content ファ イル cat, gc, type cat cat _vimrc type type _vimrc Get-Content Get-Content _vimrc パイプを使ったときに挙動が変わるオ プション -ReadCount -Raw
  16. 16. Get-Content PowerShellっぽく -ReadCount 引数によってパイプに渡される型と中身が異 なる Get-Content ._vimrc -ReadCount 1 | ForEach- Object { $_.GetType() } デフォルト パイプの次のコマンドで1行ずつ処理したい場合 例各行の長さを知る Get-Content ._vimrc -ReadCount 1 | ForEach- Object { $_.Length } Get-Content ._vimrc -ReadCount 0 | ForEach- Object { $_.GetType() } パイプへObject[]として全行やってくる ファイル全体を対象に処理をしたいとき 例行数を知る Get-Content ._vimrc -ReadCount 0 | ForEach- Object { $_.Length } -Raw Stringとしてファイル全体を読み込む Get-Content ._vimrc -Raw | ForEach-Object { $_.GetType() } パイプへファイルの中身全体が一つのStringとし てやってくる ファイル全体を1つとして処理したいとき 例ファイルの文字数を知る(含む改行) Get-Content ._vimrc -Raw | ForEach-Object { $_.Length }
  17. 17. ファイルの末尾を表示する シェルコマンドalias Cygwin(bash) tail -n 数値ファ イル名 tail -f ファイル名 cmd.exe 標準ではない PowerShell Get-Content ファ イル名-Tail 数 値 Get-Content ファ イル名-Wait Get-Content ファ イル名-Tail 数値 -Wait cat, gc, type tail tail -f access.log Get-Content Get-Content access.log -Wait Get-Content access.log -Tail 10 V3で"-Tail 数値"が指定できるように tail -f的に使いたいなら、関数を定義し ておくと良いかも function tail($content, [switch]$f) { if ($f) { Get-Content $content -Wait } else { Get- Content $content -Tail 10 } }
  18. 18. ファイルの内容を比較する シェルコマンドalias Cygwin(bash) diff ファイル1 ファイル2 cmd.exe fc ファイル1 ファ イル2 PowerShell Compare-Object $(Get-Content ファイル1) $(Get-Content ファイル2) compare, diff diff diff member_list.csv new_member_list.csv テキストファイルだけだと伝統的なdiffが 一番分かりやすい fc fc member_list.csv new_member_list.csv Compare-Object Compare-Object $(Get-Content member_list.csv) $(Get-Content new_member_list.csv) ファイル専用じゃないので出力結果もい まいち テキストファイルの比較ならGitに付属の diff.exeにパスを通して使った方が良い
  19. 19. CSVファイルを読み込んで処理する シェルコマンドalias Cygwin(bash) cut -d ',' -f位置 cmd.exe FOR /F "delims=, tokens=1,2,3" %x in (ファイル) do PowerShell Import-Csv Import-Csv ファ イル名-Header String[] ipcsv cut あくまで擬似的 FOR あくまで擬似的 構文が難解 Import-Csv 読み込むとPSCustomObjectになる Import-Csv member_list.csv | Import-Csv member_list.csv -Header id, name, payment
  20. 20. Import-Csv PowerShellっぽく 型変換 Import-Csv .member_list.csv | ForEach-Object { $_.payment = $_.payment -as [int]; $_ } 型変換した上でフィルタ Import-Csv .member_list.csv | ForEach-Object { $_.payment = $_.payment -as [int]; $_ } | Where-Object { $_.payment -ge 750 } さらに平均値と合計 Import-Csv .member_list.csv | ForEach-Object { $_.payment = $_.payment -as [int]; $_ } | Where-Object { $_.payment -ge 750 } | Measure-Object payment -ave -sum PSCustomObjectなので、テキストに比べて圧倒的に加工が簡単
  21. 21. 文字列処理 条件にマッチするファイルと行を抜き出す 文字列を置換する 文字列を抽出する
  22. 22. 条件にマッチするファイルと行を抜き出す シェルコマンドalias Cygwin(bash) grep 文字列ファ イル grep -e パターン ファイル cmd.exe findstr 文字列 ファイル findstr /R パター ンファイル PowerShell Select-String - Pattern パターン -Path ファイル Get-Content ファ イル| Where- Object { $_ - match パターン} sls grep grep -e "oota.*" member_list.csv findstr findstr /N -R "oota.*" member_list.csv Select-String Select-String -Pattern "oota.*" - Path .member_list.csv -match Get-Content .member_list.csv | Where-Object { $_ -cmatch "oota.*" }
  23. 23. -match PowerShellっぽく パイプはマッチの結果を使う場合、Select-Stringより-matchの方が使いやすい マッチする行のみにフィルタリングして Get-Content .member_list.csv | Where-Object { $_ -cmatch "oota" } その行のpaymentを抽出する Get-Content .member_list.csv | Where-Object { $_ -cmatch "oota" } | ForEach- Object { [void]($_ -cmatch "(.*),(.*),(.*)"); $Matches[3] } ただし、PowerShellの場合、正規表現マッチングを駆使するよりも、PSCustomObject に変換してしまって、型保証されたプロパティーでマッチさせる方が自然
  24. 24. 文字列を置換する シェルコマンドalias Cygwin(bash) sed -e パターン sed -E パターン cmd.exe %環境変数:置 換前文字列=置 換後文字列% PowerShell 置換対象文字 列-replace 置換 前文字列,置換 誤文字列 置換対象文字 列-creplace 置 換前文字列,置 換誤文字列 sed cat member_list.csv | sed -E 's/(.*),(.*),(.*)/1,3,2/g' %:=% set name=ootaken echo %name:oota=hibino% 正規表現置換とかはできない -creplace Get-Content .member_list.csv | ForEach- Object { $_ -creplace "(.*),(.*),(.*)",'$1,$3,$2' } 正規表現置換ができる(*⌒▽⌒*) -replaceは大文字小文字区別しない ただし、PowerShellの場合、以下同様
  25. 25. 文字列を抽出する シェルコマンド Cygwin(bash) cut -d デリミタ-f 列 awk -F デリミタ'{ print 列}' cmd.exe FOR /F "delims=, tokens=1,2,3" %x in (ファイル) do PowerShell 変数.split(文字列)[列] cut cat member_list.csv | cut -d , -f 2 awk cat member_list.csv | awk -F , '{ print $2 }' 黒魔術になりがち FOR FOR /F "delims=, tokens=1,2,3" %x in (member_list.csv) do @echo "%y" split Get-Content .member_list.csv | ForEach- Object { $_.split(",")[1] } ちょっと不格好 PSCustomObjectに変換してしまった方が PowerShellらしい処理ができる
  26. 26. 開発ツール- タブ補完 Git Subversion Maven Gradle Jenkins CLI
  27. 27. Git シェルツール Cygwin(bash) git-completion git-flow-completion cmd.exe なし PowerShell posh-git git-completion 劇的にタイプ数が少なくなる git-flow-completion git-flowを常用しているなら posh-git PowerShellでもgit-completion並に補完が 可能に インストール chocolatey choco install poshgit PsGet Install-Module posh-git
  28. 28. Subversion シェルツール Cygwin(bash) bash_completion cmd.exe なし PowerShell posh-svn Subversion PowerShell Module bash_completion 公式なインストール方法見つからず UNIX界隈ではもはやSubversionの需要がない? posh-svn 公式なインストール方法が存在 TortoiseSVN等GUIクライアントを使うことが多いと 思うが一定の需要がありそう インストール PsGet Install-Module posh-svn $PROFILEに以下を追加 .'C:UsersKenichiroOtaDocumentsWindowsPowerShell Modulesposh-svnprofile.example.ps1' Subversion PowerShell Module コマンドレット集 ZIPファイルを解凍・・・
  29. 29. Maven シェルツール Cygwin(bash) Maven Bash Completion cmd.exe なし PowerShell なし posh-mvn (太田が移植予定) Maven Bash Completion https://github.com/juven/maven-bash-completion Mavenをコマンドラインでガンガン使う 人には嬉しいかも posh-mvn PowerShellのタブ補完の勉強がてらに 太田が作成予定 TabExpansion++を拡張すると楽らしい https://github.com/lzybkr/TabExpansionPl usPlus
  30. 30. Gradle シェルツール Cygwin(bash) Maven Bash Completion cmd.exe なし PowerShell なし posh-gradle (太田が移植予定) Gradle tab completion script for Bash https://gist.github.com/nolanlawson/86 94399 Gradleをコマンドラインでガンガン使う 人には嬉しいかも posh-gradle PowerShellのタブ補完の勉強がてらに 太田が作成予定
  31. 31. Jenkins CLI シェルツール Cygwin(bash) なし cmd.exe なし PowerShell なし posh-jenkins (太田が開発予定) Jenkins CLI JenkinsをCLIからキックできる謹製CLI ほぼすべてのJenkinsの操作をCLI からできる 例 java -jar jenkins-cli.jar -s http://localhost:8080/ build sample_powershell_job 補完できるとうれしいが、現状ツー ルなし
  32. 32. PowerShell固有– Excelを呼ぶ $RunExcelFunction = { param([scriptblock] $script = {param($xl) }); $xl = New-Object -ComObject Excel.Application $wf = $xl.WorksheetFunction try { & $script $wf } finally { $wf, $xl | ForEach { [void][Runtime.Interopservices.Marshal]::ReleaseComObject($_) } } } function Average { param( [Parameter(ValueFromPipeline = $true) ] $array) $average = { param($wf) $wf.Average($array) }.GetNewClosure() & $RunExcelFunction $average }
  33. 33. PowerShell固有– Excelを呼ぶ COM, .NET, WMIとほぼあらゆるWindowsのオブジェクトを同一のインタフェースで部 品として扱える Cygwin, cmd.exeにないPowerShell固有のメリット COM 但し、メモリモデル等は各プラットフォームに依存する そのため、COMでは明示的にオブジェクトを解放しないとメモリリークする サンプルのように呼び出し部分をテンプレートメソッド化し、実際の処理のスクリ プトブロックをGetNewClosureでクロージャー化し渡すのがよい
  34. 34. タブ補完 TabExpansion++ PowerTab
  35. 35. TabExpansion++ function MvnCompletion { [ArgumentCompleter( Native, Command = 'Mvn', Description = 'Complete parameters and arguments to mvn.exe')] param($wordToComplete, $commandAst) $subCommand = "compile", "test", "package", "install" $subCommand | Where-Object { $_ -like "$wordToComplete*" } | Sort-Object | ForEach-Object { New-CompletionResult $_ $_ } } https://github.com/lzybkr/TabExpansionPlusPlus PowerShellの標準のタブ補完を拡張 下記のような動的なタブ補完が可能 Get-Command -Verb Tab インストール PowerShell iex (new-object System.Net.WebClient).DownloadString('https://raw.github.com/lzyb kr/TabExpansionPlusPlus/master/Install.ps1') PSGet Install-Module -ModuleUrl https://github.com/lzybkr/TabExpansionPlusPlus/zipball/master/ - ModuleName TabExpansion++ -Type ZIP 独自のタブ拡張が簡単に作成可能 簡易posh-mvn 左記のような関数を作成し、TabExpansion++のインストールされた パスに配置
  36. 36. PowerTab https://powertab.codeplex.com/ 同じくPowerShellの標準のタブ補完を拡張 Intellisenseのようなビジュアルな補完可能 Visual Studioな人には嬉しいかも TabExpansion++とかち合う>< インストール Chocolatey choco install powertab なぜか、64bits PowerShellで実行しても” C:WindowsSysWOW64WindowsPowerShellv1.0Module sPowerTab”に入り、” C:WindowsSystem32WindowsPowerShellv1.0Modules” にコピーし直す必要がある 独自のタブ拡張がTabExpansion++と同じよ うに書けるが、TabExpansion++の方が柔軟
  37. 37. まとめ エディタ+ CLIの人でもPowerShellがあればCygwinはもういらない diffとか一部足りないものはGitに付属ものなどで補う 最初は正規表現を活用したUNIXっぽい書き方でもよい ただし、これだと黒魔術っぽい書き方のままになる PSCustomObjectを活用したPowerShellらしい書き方のほうが短く強力 開発ツールの補完サポートの不足 TabExpansion++を活用する なければ、自分で作る&移植する エディタ+ CLIの人でもWindowsを快適かつ魅力的なプラットフォームにするPowerShell

×