読者です 読者をやめる 読者になる 読者になる

tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

複数ファイルの中身を一括置換する方法のちょっと比較(vi、sed、tr、perl)とついでにファイル名の一括置換

はじめに

perlコマンドでの一括置換方法は前に(ファイルの中身の文字列を一括置換)メモったので
今回はviとsedでの置換方法との比較です

自分の印象比較

自分的に使った印象ベースでのメリットデメリットで比較します
一般的なはなしではないと思います。

方法 メリット デメリット
vi ・目で確認しながら置換ができる
・部分置換もしやすい(n行〜m行の間とか)
複数ファイルの置換はちょっときつい
sed ・オプションとか条件式でかなりいろいろできる ・オプションとか条件式に慣れるまで大変
・元ファイルを書き換えることができない(工夫次第?)
tr ・特定文字の削除とかにはラクかも? ・いろいろできない
・文字列置換とかにはそんなに向かないかも
perl ・お手軽
・任意にバックアップファイルを作りながらの置換もできる
・ググってもオプションについてとかあまりない

サンプル

vi

1.vi *.txtとかで複数ファイルを開く
2.対象範囲の開始で「ms」と入力
3.対象範囲の終了で「me」と入力
4.コマンドモードで「:'s,'es/置換前文字列/置換後文字列/g」と入力してからEnter
5.1ファイル終わったらコマンドモードで「:n」で次ファイルへ

参考
viでの置換とか複数行コピーとか
教えてgooで説明してくれてるやつ

sed

hoge.txt内のtextをtestに置換

# sed -e 's/text/test/g' ./hoge.txt

参考
オプションとか
他の方が書いたサンプルとか

tr

hoge.txt内のタブを削除

# tr -d '\t' < hoge.txt

参考
オプションとか
サンプルとか

perl

カレントディレクトリ以下のファイルの中身の'hoge'という文字列を'fuga'に置換。
ただし、パスに.svnとつくファイルは除外する

# grep -lr hoge ./ | grep -v '.svn' | xargs perl -pi -e 's/hoge/fuga/g'

参考
ファイルの中身の文字列を一括置換

ついでにファイル名のほうの一括置換

'hoge'という文字列を含むファイル名の'hoge'を'fuga'に一括置換

# rename hoge fuga ./hoge*

ちょっと面白いor怖い使い方

あるディレクトリに下記のようなファイルがあったとします

# tree
.
`-- rename_test
    |-- hogehoge_01.txt
    |-- hogehoge_02.txt
    |-- hogehoge_03.txt
    `-- hogehoge_04.txt

①ファイル名の先頭のhogeを削除

# rename hoge "" ./rename_test/hoge*
# ls -1 ./rename_test
hoge_01.txt
hoge_02.txt
hoge_03.txt
hoge_04.txt

※単純に1回しかrenameしてくれない

②お次は先頭にhogeを追加して最初に戻す

# cd rename_test
↑いったん移動する理由も下記にメモっときます
# rename "" hoge hoge*
# ls -1
hogehoge_01.txt
hogehoge_02.txt
hogehoge_03.txt
hogehoge_04.txt

※①と違って""で先頭ってわかりいくいw

③移動しないでやった場合

# rename "" hoge ./rename_test/hoge*
rename: ./rename_test/hoge_01.txt から hoge./rename_test/hoge_01.txt への名前の変更に失敗しました: そのようなファイルやディレクトリはありません

※パス'文字列'を置換するようですね

④さらには'/'を'_'に変更してみる

# rename / - rename_test/hoge*

# tree
.

-- rename_test
-- rename_test-hoge_01.txt
-- rename_test-hoge_02.txt
-- rename_test-hoge_03.txt

`-- rename_test-hoge_04.txt

ディレクトリのパスごと変わっちゃうんですね。
これはある意味怖いから使わないほうが良いかもレベルな気がしますね。