powershellを使う

Windows7以降では標準でpowershellが使えます、という話です。

バージョン管理システム(git)のログを整形したいことがありました。
ログの中身は複数のコミットの情報があり、1コミットには複数のファイルのリストが含まれています。これらをファイル毎にコミットの情報を付加して、出力としてはCSVファイルにしたいと思いました。(後はExcelで開いてゴニョゴニョ・・・みたいな。)
でも使用中のWindowsマシンで、LinuxやFreeBSDのような、テキスト処理をする環境もなく、かといってVirutalBoxを入れることもその時は考えていなかったので、powershellを使うことにしました。

結論から言うと、使えたのですが、bashやWindowsのコマンドプロンプトとはいろいろ違うところがあって、例えば、

・スクリプトファイルを書いて実行することができるけど、そのためには予め管理者権限でスクリプトの実行を許可しなければならない。
・パイプ処理ができるけど、受け取るのは文字列のストリームではなくてオブジェクト。パイプ処理に限らず、何かコマンドレット(powershellでいうところのコマンド)を実行すると結果はオブジェクトで帰ってくる。

で、色々やった結果が下記になります。
文字コードの扱いがうまくできなかったので、gitの出力をコマンドプロンプト(cmd)で取得して、テキストエディタ(さくらエディタ)で変換する、ということをして逃げています。

# cmdで以下を実行
#
# git log --numstat --date=iso > ..\log.txt
#
# log.txtのエンコーディングをテキストエディタでUTF8からSJISに変更
#
# powershellで、このスクリプトを実行
#
# .\read_git_log2.ps1 log.txt > log.csv
#
# Excelでlog.csvを開く
# 追加行の集計(シートlogがlog.csvの内容で、A1にファイル名とすると、)
# =SUMIFS(log!E:E,log!$D:$D,"=" & Sheet1!$A1)
# 削除行の集計(シートlogがlog.csvの内容で、A1にファイル名とすると、)
# =SUMIFS(log!F:F,log!$D:$D,"=" & Sheet1!$A1)
$commit = ""
$author = ""
$date = ""
$comment = ""
$file = ""
$chgnum = ""
$chgline = ""
$plusnum = ""
$minusnum = ""
if ($args.Count -eq 0) {
"read_git_log2.ps1 logfile"
return
}
cat $args[0]| % {
$line = $_
if ($line -match '^commit.*$') {
$commit = $line -replace '^commit +', ''
$author = ""
$date = ""
$comment = ""
$file = ""
$plusnum = ""
$minusnum = ""
#$commit
} elseif ($line -match '^Author:.*$') {
$author = $line
$author = $author -replace '^Author: +',''
$author = $author -replace '<.+>',''
$author = $author.ToString().Trim()
#$author
} elseif ($line -match '^Date:.*$') {
$date = $line
$date = $date -replace '^Date: +',''
$date = $date -replace '\+0900', ''
#$date
} elseif ($line -match '^ .+$') {
$txt = $line -replace '\W',' '
$comment = "{0}{1}" -f $comment, $txt
#"comment {0}" -f $comment
} elseif ($line -match '^[0-9-]+\W+[0-9-]+\W+.*$') {
$file = $line -replace '^[0-9-]+\W+[0-9-]+\W+(.*)$','$1'
$plusnum = $line -replace '^([0-9-]+)\W+[0-9-]+\W+.*$','$1'
$minusnum = $line -replace '^[0-9-]+\W+([0-9-]+)\W+(.*)$','$1'
"{0}`t{1}`t{2}`t{3}`t{4}`t{5}`t{6}" -f $commit, $author, $date, $file, $plusnum, $minusnum, $comment
}
}

powershellはクセがあって使いづらいこともありますが、標準で入っていることもあり、使えると便利だと思います。

  • このエントリーをはてなブックマークに追加