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のように指定する)、文字列は(文字列でありながら)改行コードで区切られた複数の行としてみなされる
補足
[]の中に.や*を入れた場合はメタキャラクタではなくリテラルとなり、文字通り.や*にしかマッチしない