2015年8月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

最近のトラックバック

最近買った本(Amazon.co.jp)

広告(Amazon.co.jp)

広告(Google AdSense)

無料ブログはココログ

カテゴリー「Shell Script」の1件の記事

2011年8月25日 (木)

PowerShell入門: 複数ファイルの中の文字列を一括変換する。

とりあえず、覚え書き。

最近のGNU sedには-i(--in-place)オプションというのが追加されていて、オリジナルファイルに処理結果を上書きすることができる。 たとえば、ディレクトリOEBPS配下の全てのhtmlファイルについて、html要素にxml:lang="ja"属性を追加したいときは、以下のコマンドを実行すれば良い。

$ find OEBPS -name '*.html'|xargs sed -i -e's/^<html/<html xml:lang="ja"/'

前回の記事について、Windows環境でも同様の処理を行う必要があったため、最近流行(?)のPowerShellで一行コマンドを作成してみた。 上記の例の場合、以下のコマンドを実行すれば良い。(実際には一行で入力すること。)

PS> gci -r -i *.html OEBPS|
  %{(gc -en UTF8 $_)|%{$_ -replace'^<html','<html xml:lang="ja"'}|sc -en UTF8 $_}

この例では対象のファイルが全て上書きされるのが前提だが、置換対象の文字列を含むファイルのみを上書きしたい場合は、以下のようにSelect-Stringを挟めば良い。

PS> $f='^<html';gci -r -i *.html OEBPS|Select-String $f -List|
  %{(gc -en UTF8 $_.Path)|%{$_ -replace$f,'<html xml:lang="ja"'}|sc -en UTF8 $_.Path}

説明

  • gci(Get-ChildItem)で、ディレクトリ配下から指定したパターンに一致するファイルを取得する。

  • Select-Stringで、置換対象のパターンを含むファイルのみを取得する。Select-StringはMatchInfo オブジェクトを返すため、後の処理では$_.Pathでパス名を取得している。また、デフォルトでは大文字と小文字は区別されないため、区別したいときは-CaseSensitiveオプションを追加する。

  • 最初の%(ForEach-Object)ブロックにて、ファイルを一つずつ処理する。

  • gc(Get-Content)で、ファイルの中身を取得する。尚、gcを丸括弧で囲むことで、ファイルの中身を一度に読み込んでオブジェクトが生成される。これにより、scでファイルを上書きするときにファイルが使用中でエラーになるのを回避する。

  • 次の%(ForEach-Object)ブロックで、ファイルを一行ずつ処理する。

  • -replace演算子で、置換対象の文字列を置換する。尚、デフォルトでは-replaceは小文字と大文字を区別しない。区別するには-creplaceを使用する。また、区別しないことを明示するには-ireplaceを使用する。

  • ファイルの中身がUTF-8のため、gcとscに-en UTF8オプションを指定する。

以上

2011/08/26 記事のタイトル、及び、本文の説明を修正した。
2011/09/02 記事のカテゴリーを変更した。
2011/09/07 Select-Stringの記述を追加、及び、説明を修正した。
2011/09/21 記事のリンク、及び、説明を修正した。