sedが出力ファイルによって異なる動作をするのはなぜですか?

sedが出力ファイルによって異なる動作をするのはなぜですか?

私が実行した場合:

cat messages.txt | sed -e 's/a/a/g' > messages.txt

大きなファイル(2500行以上)では、cygwinのコマンド以降に生成されたファイルには約900行しかありませんが、gentooでは行がないことがわかりました。しかし、私が走ったら

cat messages.txt | sed -e 's/a/a/g' > other_messages.txt

すべての行をそのままにしてください。

私の質問はなぜ

cat messages.txt | sed -e 's/a/a/g' > other_messages.txt
rm messages.txt
mv other_messages.txt messages.txt

ベストアンサー1

ベルシュミットの答えsed を使用する場合に最適です。しかし、より一般的な意味では、次のようなアンチパターンがあります。

cat infile | filter > infile

多くの問題が発生する可能性があります。たとえば、次のファイルがあるとしますinfile

Hello
World

そして、次のコマンドを実行してください。

cat infile | tr "[:upper:]" "[:lower:]"

わかりました。

hello
world

ただし、実行すると空のcat infile | tr "[:upper:]" "[:lower:]" > infileファイルが表示されます。なぜ?

まあ、出力リダイレクト演算子を使用すると、>「私の標準出力をこのファイルに入れ、ファイルが存在する場合は上書きされます」と言うことです。これでフィルタリングのためにこれがうまくいくはずだと思うかもしれません。コンパイラは元のすべての行を返します。ファイル。しかし、しばしば起こるのは、シェルが行を読み取る前にファイルを破損することです。その後、フィルタコマンドは空のファイルから行を読み込み、何も見つからないため、なしを返します。いくつかの場所では、ファイルが破損する前にいくつかの行を読むのに十分な「幸運」があるかもしれませんが、このパターンを完全に避けるのが最善です。

この特定の問題を解決するには、いくつかのオプションがあります。一つは、単に以下を行うことです。

cat infile | filter > tmpfile; mv tmpfile infile

一時ファイルが他のファイルを破損させたり、他の不快なことをしないようにする必要がある場合は、確認してください(およびmktemp参照)。man mktempinfo coreutils mktemp

もう1つのオプションは、以下spongeで使用することです。その他のユーティリティ

さらに、これらの例の多くは猫に役に立たない用途

おすすめ記事