• ベストアンサー

同じ名前のファイルにリダイレクト

あるファイルを処理し、そのファイルにそのままリダイレクトして書き出そうとした場合の処理に関してです。 例) sed 's/aaa/bbb/' hoge.txt > hoge.txt このようにするとhoge.txtの中身が消えてしまいます。 別名のファイルに書き出してmvすればよいのですが、なぜできないのか納得ができず悩んでいます。 お分かりの方いらっしゃればお教えください。

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

  • ベストアンサー
  • Toshi0230
  • ベストアンサー率51% (836/1635)
回答No.3

No1 の方が書いているとおり、Linuxに限らず、UNIX系OSで(少なくともcsh系では)リダイレクトによって出力をファイルに落とそうとすると、出力先のファイルがまず作られてからコマンドが実行されます。 このとき、既存のファイルと同じ名前のファイルを出力先に指定すると、強制的に空ファイルによって上書きされます。 (なんでそういう設計になっているかは知りません) ちなみにMS-DOS(試してないけどたぶんWin2k以上のコマンドプロンプトも)では、リダイレクトの際はまずテンポラリファイルに出力されてからリダイレクト先のファイルにコピーされるため、質問文のような記述をしても問題なく実行結果が出力されます。

skip_jack
質問者

補足

詳しい説明ありがとうございました。

その他の回答 (2)

  • asfd
  • ベストアンサー率21% (25/117)
回答No.2

シェルの仕様です。既存のファイルをリダイレクト先に選ぶと、 ファイルサイズを0にします。その後、sedが実行されます。 なぜ、こんな仕様になっているのかは分かりませんが、この仕様のが 分かりやすいのは確かかと、、

skip_jack
質問者

お礼

そういう仕様なんですね。 納得しました。

  • gatyan
  • ベストアンサー率41% (160/385)
回答No.1

sedが実行される前に、シェルによってhoge,txtがoutputモードでオープンされるからです た ぶ ん

skip_jack
質問者

お礼

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

関連するQ&A

  • 置換コマンド

    freeBSD5.3を使用している初心者です。 あるディレクトリ以下の全ファイルに対し、一度に内容の文字を置換したいのですがうまくいきません。 例えば /hoge/aaa.txt /hoge/bbb.txt /hoge/ccc.txt と、/hoge以下に3ファイルがあり、このファイルにAAAという文字列があるなら、AAAをBBBにしたいと思っています。 sed s/AAA/BBB/g /hoge/* とすると、置換後の中身が表示はされますが、それに置きかわったファイルは/hoge/以下に保存されていません。(もとのAAAのまま) できたら、/hoge 以下の置換されたファイルを/hoge2以下に同じ名前で保存させたいと思っています。 どなたか是非アドバイスお願いいたします。

  • sedでの変更をファイルに反映させる

    aaa.txtというファイルの中身が Welcome China だったとして、これをWelcome Indiaに変更したファイルを生成したい場合、 sed s/China/India aaa.txt > bbb.txt でよいかと思うのですが、aaa.txtの中身を直接変更したい場合、 sed s/China/India aaa.txt > aaa.txt としてしまうと、aaa.txtの中身が空っぽになってしまいます。エディタで開いて、置き換えをすればよいのですが、エディタを使わないで、ファイルの中にある単語の置き換えをし、ファイルに直接反映させる方法はないでしょうか。  できればsedを使った方法で、知りたかったのですが・・。

  • ファイル中の数行を抜き出す処理について(シェル)

    ファイルaaa.txtの2行目から4行目を抜き出し、 ファイルbbb.txtに格納する方法として、 sed -n '2,4p' aaa.txt > bbb.txt がありますが、 変数を使用し、 start=2 end=4 sed -n '${start},${end}p' aaa.txt > bbb.txt とすると、エラーが発生します。 どうすればよろしいのでしょうか。

  • シェルでリダイレクトができない

    bashを使っているのですが、 シェルの中で、 ./実行ファイル hoge1 hoge2 > hoge.txt という感じで二つの引数を使って動作する実行ファイルの標準出力を、リダイレクトしたいです。 ですが、テキストに出力をリダイレクトできません。 こんな感じの書き方でリダイレクトできないもんなんでしょうか? 教えて欲しいです。 よろしくお願いします。

  • SEDの使い方

    こんにちは。 sedである複数行のパターンにマッチしたら置き換えるということをしたいのですが上手くいきません。 たとえば、 test.txt aaa bbb ccc に対して、 sed -i.bak s/aaa/aaa'\n'111/g test とすると、 test.txt aaa 111 bbb ccc となります。 これを戻す方法として、 sed -i.bak s/aaa'\n'111/aaa/g test としても、元に戻りません。 sedを用いで元に戻す方法をご教示いただけないでしょうか。 よろしくお願い致します。

  • Windowsから直接起動するアプリにリダイレクトを設定するには?

    Windowsから直接起動するアプリにリダイレクトを設定するには? 「ファイル名を指定して実行」から直接アプリを起動し、それにリダイレクトを設定したいのですが、指定したファイルに出力されずに困っています。 例.「ファイル名を指定して実行」→「ipconfig > c:\hoge.txt」を入力= コンソールに出力 コマンドプロンプト上から「ipconfig > c:\hoge.txt」を実行するとhoge.txtに出力されるので、もしかしたらリダイレクト機能はWindowsではなく、コマンドプロンプトが持ってる?と疑っています。 だとしたら、Windowsから直接アプリを起動する場合、リダイレクトは設定できないことになりますが、この認識であっているでしょうか? 環境:Windows XP

  • 外部パラメータを使用したファイルの作成・書き込み

    テキストファイルに以下の内容が書かれています。 ファイルパス:/aaa/bbb/ccc ファイル名:ファイル.txt これを読み込んで $filepath = /aaa/bbb/ccc $filename = ファイル.txt となっています。 この時(「ファイル.txt」は存在しません。)、以下のような処理を行うと「/aaa/bbb/ccc」ではなく、「/aaa/bbb」に「ファイル.txt」が作成されるのですが、なぜでしょうか?? open(TXT, ">> $filepath/$filename"); flock(TXT, 2); print TXT $header; flock(TXT, 8); close(TXT); この処理の前に$filepathの値を調べましたが、確かに「/aaa/bbb/ccc」となっています。 何か注意する点や、ここが問題では?と言うようなことがあれば教えてください。

    • ベストアンサー
    • Perl
  • awkの入力ファイルをリダイレクト先にする方法

    ---------hoge.txt--------- hoge hoge hoge ------------------------- 等としておいて、 $ awk '{print NR":"$1;}' hoge.txt とすると標準出力に ------------------------- 1:hoge 2:hoge 3:hoge ------------------------- と表示されますが、これを $ awk '{print NR":"$1;}' hoge.txt > hoge.txt と自分自身にリダイレクトするとhoge.txtは空になってしまいます。 hoge.txtに上の標準出力を上書きするにはどのように書けば良いのでしょうか、教えてください。 awkだけでなく、テキストファイルを入力にできるコマンド一般についても 上記のようなことができる方法があれば、教えていただきたいです。

  • sedでの改行置換

    sedを用いた処理で質問があります。 出力結果の改行を置換して一列として表示しようとしているのですが、どうもうまくいきません。 (perlは敢えて使いません) 例えば、以下のようなファイルがあるとして、 $ cat hoge.txt hoge boo bar この出力結果を加工して、「hoge boo bar」のように、 改行をスペースに置換して一行として表示したい場合は、どのようにすれば良いでしょうか? ちなみに、以下のような使い方だと、うまくいきませんでした。 $ cat hoge.txt | sed 's/\ > / /g' $ cat hoge.txt | sed 's/\n/ /' ■実行環境 OS : RedHat EL 1 sedのバージョン : sed-4.0.7-3 宜しくお願い致します。

  • sedでファイルで条件指定の場合

    スクリプト初心者です。 sedコマンドを使用して文字列の置換をおこないたいのですが、条件がたくさんあるため、 条件部分をシェルのファイルと別ファイルにして実行したいです。 その際、シェル実行時の引数を条件ファイルに入れたいのですが、通常の文字列扱いになってしまい困っています。 アドバイスをお願いいたします。 ・test.sh  find $1 -type f | xargs sed -i -f mypattern.sed ・mypattern.sed  s|${1}aaa|/bbb|g test.sh hoge と実行した場合 "hogeaaa" を "bbb" に置換したいです。