sedがまじで便利。

使いこなすと鬼。
個人的には、対話的な編集処理はvim、一括処理はsedって感じ。

で、sedの使い方とかまとめてみようかな、とか思ったんだけど、ちょいとまとめきれん...。

ので、うちが時々使うsedの使い方をば。

ニコニコとかの動画を保存する。

さっそくアレ気な小見出しですいません...(д
よく使うのがこれなんで。

# cacheフォルダへ移動
$ cd ~/.mozilla/firefox/ちょめちょめ.default/Cache/

# とりあえずVideoファイルを列挙してみる。
$ file * | grep Video
BF3F3C06d01: Macromedia Flash Video

# grepと同じヿが -nと"/パターン/p"でできる。
$ file * | sed -n "/Video/p"
BF3F3C06d01: Macromedia Flash Video

# で、さらに無駄な":"以降を消す。
$ file * | sed -n "/Video/s/:.*$//p"
BF3F3C06d01

# そいつをcpでコピーする。ufは更新があったときのみ上書き。
$ cp -uf $(file * | sed -n "/Video/s/:.*$//p") ~/Movie/niconico/
`BF3F3C06d01' -> `/home/goth/Movie/niconico/BF3F3C06d01'

# あとはこれをループで回しておけば勝手に動画が保存されていく。
$ while true; do cp -uf $(file * | sed -n "/Video/s/:.*$//p") ~/Movie/niconico/; sleep 30; done

まぁ、弱点としてはファイル名がキャッシュのファイル名になってしまうことか...。
ちなみにうちの動画ディレクトリはひたすら猫ばかりです(///)
おらほの猫ら最高♪


と。いうことでポイントは-nと"p"
sedは普通はスクリプトに処理されなかった行はそのまんま出力するのだが、-nをいれるとそれをしなくなる。
で、これだと何も表示されないので"p"つまりprintで明示的に表示をしてやる。
スクリプトの先頭に"/パターン/"をいれて置くとパターンにマッチした行だけに処理を行う。

sed -n "/パターン/p"

ならパターンにマッチいた行だけを表示、つまり、grep的な挙動になる。
で、

sed -n "/パターン1/s/パターン2/パターン3/p"

は、パターン1にマッチした行にかぎり、パターン2をパターン3に置換して表示。

sed -n "/Video/s/:.*$//p"

なら、"Video"を含む行に対して、":.*$"つまり、":"以降を""に置換して表示。
ということ。
grepしてそれからsed、なんてナンセンス!
-nと"p"をうまく使って一発でやってしまおう!!

ファイルを編集する

これはまぁ、もうちょっと実用的(?)な利用法。

なんだけど、いい例が思い浮かばないな...。

たとえばシェルスクリプトをひたすら作りまくったはいいけどシバン書き忘れたとか?
そんなときは

# たとえばシェルスクリプトがあったとして、
$ ls
fuga.sh  hoge.sh

# よくよく考えたらシバン書き忘れた...
$ cat hoge.sh
echo "this is shell script"

# にしてもナンセンスなスクリプトだな、おぃ。
$ cat fuga.sh
echo "this is shell script, too."

# そんな時はsedで。
$ sed "1i #!/usr/bin/env bash \\" *
#!/usr/bin/env bash
echo "This is shell script, too."
echo "this is shell script"

# ちゃんとできてるか確認できたら-iを追加。
$ sed -i "1i #!/usr/bin/env bash \\" *

# 各ファイル後とにsedスクリプトが実行されます。
# 上の実行結果にはシバンが一個しか書いてないけど、ちゃんと各ファイルごとに実行されますよ。
$ cat hoge.sh
#!/usr/bin/env bash
echo "this is shell script"

$ cat fuga.sh
#!/usr/bin/env bash
echo "this is shell script, too."


ってな感じでたくさんのファイルに一括処理が可能。
ちなみに

$ sed "1i #!/usr/bin/env bash \\" hoge.sh > hoge.sh

はNG。
ファイルがぶっ壊れます。


"1i #!/usr/bin/env bash \\"
の意味は
"1i" ... 1行目の手前に挿入(insert)
"#!/usr/bin/env bash" ... 実際に挿入する内容
"\\" ... iコマンドの終わり。
とうぜん、次の行に追加で、"a"(append)もあります。


あと便利そうなのは"d"(delete)
当然削除。
"4d"とかなら4行目を削除。
"4,6d"だと4行目から6行目を削除。
"/パターン/,6d"だとパターンにマッチした行から6行目を削除(マッチした行が6より大きければマッチした行だけ)。
"/パターン/,+3d"だとマッチした行から続く3行を削除(複数あればすべて)。
まぁ、-iをつけずに確かめて、ちゃんと動くこと確かめてから-iをつけてくださいな。


その他詳しくは"info sed"で調べてちょ。