あるディレクトリ以下の、ある拡張子を持つファイルの、特定の文字列を一括で置換できるコマンドはあるでしょうか。
例えば、/usr/local/以下のhtml拡張子のファイルの、「jis」という文字列を「euc」に一括で置換するコマンドです。
ちなみに
find /usr/loca/ -name '*.html' -exec sed 's/jis/euc/g' {} > tmp \; -exec mv tmp {} \;
としたらうまくいきませんでした。
perl の -i オプション (対象ファイルの更新操作)が便利です。
find /usr/local/ -name '*.html' -exec perl -ipe 's/jis/euc/g' {}
find . -name '*.html' -type f -exec sed 's/jis/euc/g w tmp' {} \; -exec mv tmp {} \;
で、手元の簡単な試験では成功しました。
おそらく問題は、
- exec sed 's/jis/euc/g' {} > tmp
のところで、tmp へのリダイレクトは exec で実行した sed の出力をリダイレクトしているのではなく、find コマンドの出力をリダイレクトしていると思います。
回答ありがとうございます。
試してみたところ、パターンがマッチした行しか、ファイルに出力されませんでした…
UNIX/Linuxコマンドはよく知りませんが調べてみたところ、
なお、DOS とは違って UNIX では メタキャラクタの展開はシェルの役割なので、
% mv *.txt *.txt.bak
などとしても拡張子の一括変換はできない。この場合、csh・tcsh なら foreach、sh・bash なら for を使うとよい。
と書いてありました。
回答ありがとうございます。
ファイル名の置換ではなく、ファイルの中身の置換を試みています。
1番目の回答で、sedではマッチした行しか出力されないのでしたら、その部分をawkに置き換えたものはいかがでしょう。
これなら、マッチする行、しない行ともに、全ての行が出力されます。
find . -name '*.html' -exec awk '{gsub(/jis/, "euc"); print $0 >"tmp"}' {} \; -exec mv tmp {} \;
回答ありがとうございます。
なるほど、awkコマンドですか。
リベンジです(^^;
試してみたところ、パターンがマッチした行しか、ファイルに出力されませんでした…
でした。
で、ちょっと格好悪いのですが、まず、下記のシェルスクリプトのファイルを作ります。
--------------------------------------------------------
#!/bin/sh
sed 's/jis/euc/g' $1 >tmp && mv tmp $1
--------------------------------------------------------
このファイルを仮に、change という名前でカレントディレクトリに置いたとして、
find . -name '*.euc' -type f -exec ./change {} \;
とします。
シェルスクリプトはエラー処理や単独で利用する場合に便利にしようと思ったりすると改善の余地はあります。
再び回答ありがとうございます。
確かに、シェルスクリプト使うとできそうですね。
シェルスクリプト使わないで方法を自分で見つけたので、一応ご報告して、質問を終了したいと思います。
find /usr/loca/ -name '*.html' -exec sed -e '/jis/!w tmp' -e 's/jis/euc/w tmp' {} > tmp \; -exec mv tmp {} \;
まったくきれいじゃないですね(^^;
perl の -i オプション (対象ファイルの更新操作)が便利です。
find /usr/local/ -name '*.html' -exec perl -ipe 's/jis/euc/g' {}
回答ありがとうございます。
perlだとファイル更新できるんですね!
回答ありがとうございます。
perlだとファイル更新できるんですね!