UNIXコマンドの質問です。

あるディレクトリ以下の、ある拡張子を持つファイルの、特定の文字列を一括で置換できるコマンドはあるでしょうか。
例えば、/usr/local/以下のhtml拡張子のファイルの、「jis」という文字列を「euc」に一括で置換するコマンドです。
ちなみに
find /usr/loca/ -name '*.html' -exec sed 's/jis/euc/g' {} > tmp \; -exec mv tmp {} \;
としたらうまくいきませんでした。

回答の条件
  • 1人2回まで
  • 登録:2006/06/20 13:33:46
  • 終了:2006/06/20 16:20:56

ベストアンサー

id:toohigh No.5

toohigh回答回数291ベストアンサー獲得回数372006/06/20 16:04:37

ポイント30pt

perl の -i オプション (対象ファイルの更新操作)が便利です。

find /usr/local/ -name '*.html' -exec perl -ipe 's/jis/euc/g' {}

http://www.stackasterisk.jp/tech/program/perl04_04.jsp

id:takoma

回答ありがとうございます。

perlだとファイル更新できるんですね!

2006/06/20 16:19:41

その他の回答(4件)

id:JULY No.1

JULY回答回数966ベストアンサー獲得回数2472006/06/20 14:43:40

ポイント15pt

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 コマンドの出力をリダイレクトしていると思います。

id:takoma

回答ありがとうございます。

試してみたところ、パターンがマッチした行しか、ファイルに出力されませんでした…

2006/06/20 15:08:23
id:villain No.2

villain回答回数174ベストアンサー獲得回数122006/06/20 15:07:52

ポイント10pt

UNIX/Linuxコマンドはよく知りませんが調べてみたところ


なお、DOS とは違って UNIX では メタキャラクタの展開はシェルの役割なので、

% mv *.txt *.txt.bak

などとしても拡張子の一括変換はできない。この場合、csh・tcsh なら foreach、sh・bash なら for を使うとよい。


と書いてありました。

id:takoma

回答ありがとうございます。

ファイル名の置換ではなく、ファイルの中身の置換を試みています。

2006/06/20 15:09:41
id:tadashi0805 No.3

tadashi0805回答回数287ベストアンサー獲得回数292006/06/20 15:38:05

ポイント30pt

1番目の回答で、sedではマッチした行しか出力されないのでしたら、その部分をawkに置き換えたものはいかがでしょう。

これなら、マッチする行、しない行ともに、全ての行が出力されます。

find . -name '*.html' -exec awk '{gsub(/jis/, "euc"); print $0 >"tmp"}' {} \; -exec mv tmp {} \;

id:takoma

回答ありがとうございます。

なるほど、awkコマンドですか。

2006/06/20 16:12:35
id:JULY No.4

JULY回答回数966ベストアンサー獲得回数2472006/06/20 15:39:54

ポイント15pt

リベンジです(^^;

試してみたところ、パターンがマッチした行しか、ファイルに出力されませんでした…

でした。

で、ちょっと格好悪いのですが、まず、下記のシェルスクリプトのファイルを作ります。

--------------------------------------------------------

#!/bin/sh

sed 's/jis/euc/g' $1 >tmp && mv tmp $1

--------------------------------------------------------

このファイルを仮に、change という名前でカレントディレクトリに置いたとして、

find . -name '*.euc' -type f -exec ./change {} \;

とします。

シェルスクリプトはエラー処理や単独で利用する場合に便利にしようと思ったりすると改善の余地はあります。

id:takoma

再び回答ありがとうございます。

確かに、シェルスクリプト使うとできそうですね。

シェルスクリプト使わないで方法を自分で見つけたので、一応ご報告して、質問を終了したいと思います。

find /usr/loca/ -name '*.html' -exec sed -e '/jis/!w tmp' -e 's/jis/euc/w tmp' {} > tmp \; -exec mv tmp {} \;

まったくきれいじゃないですね(^^;

2006/06/20 16:15:44
id:toohigh No.5

toohigh回答回数291ベストアンサー獲得回数372006/06/20 16:04:37ここでベストアンサー

ポイント30pt

perl の -i オプション (対象ファイルの更新操作)が便利です。

find /usr/local/ -name '*.html' -exec perl -ipe 's/jis/euc/g' {}

http://www.stackasterisk.jp/tech/program/perl04_04.jsp

id:takoma

回答ありがとうございます。

perlだとファイル更新できるんですね!

2006/06/20 16:19:41
  • id:villain
    すみません。
    質問の内容・意図を勘違いしました。
    本当に申し訳ありません。

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません