TMP="$$.FILE"
#Process puts contents into TMP
cat "$TMP" | sort | head > "$TMP"
私は既にファイルが空でないことを確認しました。 > "$TMP"
がなければ、何かを出力しますが、同じファイルに再び格納されているときは空です。何が原因だろうか?これが原因でファイルが空になるのはなぜですか?
TMP="$$.FILE"
#Process puts contents into TMP
cat "$TMP" | sort | head > "$TMP"
私は既にファイルが空でないことを確認しました。 > "$TMP"
がなければ、何かを出力しますが、同じファイルに再び格納されているときは空です。何が原因だろうか?これが原因でファイルが空になるのはなぜですか?
これらのプロセスはすべて並列で実行されるため、catコマンドで読み込む前にheadコマンドでファイルが切り詰められます。
あなたが望む結果を得るには、ソート出力を別のファイルに書き込んで、それを元のファイルに移動する必要があります。
cat "$TMP" | sort | head > "$TMP".new
mv "$TMP".new "$TMP"
同時にファイルに書き込んだり読み込んだりすることはできません。ここでは何が起こるかおおよそ次のとおりです。
> "$TMP"
ファイルは、ファイルを切り捨て書き込み、のためにオープンされます。cat "$TMP"
今から空白のファイルを読み込みます。実際にファイルを修正するためのコマンドは、実際にはカバーの下に一時的なファイルシャッフルを実行します。たとえば、sed -i
は入力ファイルを処理し、結果をinput.tmp
に保存し、最後にmv input.tmp input
を実行して元のファイルを上書きします。あなたはそのモデルに従うべきです。
それで解決策は何ですか?別のTMPファイルを作成しますか? – Strawberry
実際に何かが起こる前に、最初のパイプが読み取るファイルを最後のパイプで切り捨てます。だから、cat
は、head
への呼び出しがすぐに切り捨てられたファイルを読み込もうとします。これが問題の原因です。 、あなたはここでcat
を関連ノートで>
演算子「すぐにこのファイルを切り捨てた後、プロセスはファイルにその標準出力を書き込む持っていることを意味シェル演算子である。
必要はありません。
てみてくださいこの代わりに:!
TMP="$$.FILE"
sort <"$TMP" | head > "$TMP.tmp"
mv "$TMP.tmp" "$TMP"
1 - ありがとう – Strawberry
'ソート "$ TMP" |ヘッド> "$ TMP" .new && mvは "$ TMP" .new "$ TMPは、"'ファイルをつかうから続けますエラーがあれば(そして、 'cat'は休憩になります) –