sed/正規表現メモ
sedについて
改行コードを変更したい
- 改行コードを
\n
から\r\n
に(つまりLinux(LF)からWindows(CR+LF)に)変換したい sed -i 's/\n/\r\n/' file
はダメで、sed -i 's/$/\r/' file
とする必要がある
パターンスペース
$
(行末)を\r
(CR)で変換しているのに、その結果が\r\n
(CR+LF)になっている点が不思議だが、これはパターンスペースのしわざである- 「sedは読み込んだ行の行末にある改行を削除してパターンスペースと呼ばれるバッファに格納したうえでテキスト処理をし、最後にパターンスペースの内容に改行をつけて出力する」from http://shantiworks.info/2012/08/10/sedで改行を含む複数行の文字列を置換/
- パターンスペース上で
$
を\r
に変換したあと、出力する際に\n
を付けるため、\r\n
になる
POSIX sedとGNU sed
- POSIX sedはBSD(OSX)に含まれるもので、GNU sedはLinuxに含まれるもの
- 直前の1文字以上の繰り返しを表現する
+
はPOSIX sedにもGNU sedにも含まれない正規表現だが、GNU sedでは\+
が定義されている- c.f. 正規表現メモ
- ファイルを上書きする
-i
オプションはPOSIX sedには含まれずGNU sedには含まれている - POSIX sedの
-i
オプションについては以下参照
(man sed より) -i extension Edit files in-place, saving backups with the specified extension. If a zero-length extension is given, no backup will be saved. It is not recommended to give a zero- length extension when in-place editing files, as you risk corruption or partial content in situations where disk space is exhausted, etc.
使用例 (POSIX sed)
$ cat test.txt aaa bbb ccc
$ sed -e 's/\(b\{2\}\)/\1zzz/g' -e 's/\(c\{2,\}\)/xxx\1/g' test.txt aaa bbzzzb xxxccc
- マッチした行のみ処理を実行して表示
sed -n 's/\(bbb\)/\1?/p' test.txt bbb?
- マッチした行に、改変した行を加える場合
$ sed '/bbb/p; s/bbb/zzz/g' test.txt aaa bbb zzz ccc # sedはデフォルトでマッチしない行を出力し、マッチした行は処理を実行する # pコマンドでその行を表示し、sコマンドでその行を置換している
- 1行目/最終行のみ/以外を表示
$ sed -n 1p test.txt aaa $ sed -n \$p test.txt ccc # nオプションでマッチした行のみ表示する $ sed 1d test.txt bbb ccc $ sed \$d test.txt aaa bbb
正規表現について
- 考え方として、文字列は一つ以上の行から形成される
^
と$
は行の先頭と末尾にマッチし、¥A
と¥Z
は文字列の先頭と末尾にマッチする- なお、ピリオドは改行コードにマッチしない
m修飾子
- m修飾子を用いない場合、文字列は一つの行としてみなされ、
^
と¥A
、$
と¥Z
は同じ意味になる m修飾子を用いる場合(//mのように指定する)、文字列は(文字列でありながら)改行コードで区切られた複数の行としてみなされる
補足
[]
の中に.
や*
を入れた場合はメタキャラクタではなくリテラルとなり、文字通り.
や*
にしかマッチしない