• ベストアンサー

複数のファイルをsedで処理したいけど・・・

こんにちは。sedでテキストファイルの文字の変換をしています。でも、 001.txt 002.txt 003.txt のように同じ変換をしたいファイルが延々とあります(涙) sed -e 's/a/b/g' 001.txt > 001convert.txt のように一つずつやっているととても大変です。 なのでワイルドカードが使えるかなと sed -e 's/a/b/g' *.txt > *convert.txt とやったら「*convert.txt」というのが一つだけできてしまいました。 変です・・・。 正しくはどのようにコマンドを書けばいいのですか? 教えてください!!

質問者が選んだベストアンサー

  • ベストアンサー
  • kuroizell
  • ベストアンサー率55% (95/170)
回答No.2

perl -pi -e 's/a/b/g' *.txt フォルダがいくつもある場合に根こそぎやるのなら、 find ./ -name "*.txt" | xargs perl -pi -e 's/old/new/g' どうしてもsedコマンドを使いたければ、長い入力になるので予めスクリプト作ったほうが良いでしょう。 #!bin/sh echo -n '置換前: ' read str1 echo -n '置換後: ' read str2 echo '置換する対象(拡張子)を指定して下さい' echo -n '入力: ' read Ext find ./ -type f -name "*.$Ext" | while read f do f2=${f}_tmp sed -e "s/$str1/$str2/g" "$f" > "$f2" mv -f "$f2" "$f" done

rabitwo
質問者

お礼

ご回答ありがとうございます。 perlというのはプログラミング言語だと思っていましたが教えていただいたとおりにやったら複数のファイルがちゃんと処理できました。不思議です。 それから、シェルスクリプトのほうもちゃんと実行できて複数のファイルをちゃんと処理できました。echo以外意味がわかってないので不思議です(echoに -nが入ってるのもよくわかってません)。 願いは叶ったけど魔法の言葉の意味がわからない不思議な気分です。

その他の回答 (2)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

シェルのファイル名展開は、先に行われます。 Windowsのコマンドプロンプトとの大きな違いの一つです。 sed -e 's/a/b/g' *.txt > *convert.txt は sed -e 's/a/b/g' 001.txt 002.txt 003.txt > *convert.txt に展開されて実行します。(ここで、普通は「*convert.txt」が展開できないのでエラーになるのですが) さらに、 > は出力先を指定するもので、実際に実行するコマンドは sed -e 's/a/b/g' 001.txt 002.txt 003.txt ということになります。 コマンドプロンプトみたいに ren *.txt *.ini で拡張子だけ変わる、とかいう動作はしません。 それぞれのファイル毎にやりたいのなら、 sed -e 's/a/b/g' 001.txt > 001convert.txt のように一つずつやることになります (1)力技: sed -e 's/a/b/g' 001.txt > 001convert.txt sed -e 's/a/b/g' 002.txt > 002convert.txt sed -e 's/a/b/g' 003.txt > 003convert.txt (以下略)と変換したいファイルの分だけ書いたテキストファイルを用意してsh 「↑のテキストファイル」で実行 (2)いくぶんスマートな方法 forを使う。bashの場合 for i in *.txt ; do sed -e 's/a/b/g' $i > "${i%.txt}convert.txt" ; done

rabitwo
質問者

お礼

詳しい説明ありがとうございます。 Windowsのコマンドプロンプトと並び方が違うって初めて知りました!! ところで(1)の力技はコマンド一つずつやるのとあんまり変わりませんね・・・。 (2)は試してみたいです。C言語のfor文と違って何回繰り返すのかって書かないのですね。不思議な文法です・・・。

noname#140045
noname#140045
回答No.1

下記、URLのようにしてやればいいのではないでしょうか。 直接、コマンドを入力するよりもシェルファイルにした方がより確実かと思います。

参考URL:
http://zapanet.info/blog/item/854
rabitwo
質問者

お礼

ありがとうございます。 ご紹介のページ、質問を書く前にも見たのです。それを参考にして for FILE in *.txt; do cp $FILE $FILE.bak; sed -e "s/a/b/g" $FILE.bak > $FILE; done とコマンドラインでやってみたのですがしばらく時間が経ってもプロンプトが戻ってこないので中止しました。上のコマンドの意味がわからないのでどこかミスがあったかもしれません。

関連するQ&A