私はこれが他の質問と一種の重複であることを知っています(このソートコマンドが空のファイルを提供するのはなぜですか?)しかし、与えられた答えに基づいて質問を拡張したいと思います。
注文する
shuf example.txt > example.txt
シェルがファイルをミックスする前にカットしてブレンドする空のファイルのみを残すため、空のファイルが返されます。しかし、
cat example.txt | shuf > example.txt
予想通りスクランブルされたファイルが生成されます。
パイプメソッドは機能しますが、単純なリダイレクトが機能しないのはなぜですか?コマンドを実行する前にファイルが切り捨てられた場合、2番目の方法も空のファイルを残してはいけませんか?
答え1
問題は、ファイルの読み取りが開始さ> example.txt
れる前にファイルの書き込みが開始されることです。shuf example.txt
だからまだ出力がないので空でexample.txt
、空のshuf
ファイルを読み込み、shuf
この場合には出力がないので最終結果は空になります。
他のコマンドでも同じ問題が発生する可能性があります。> example.txt
ファイルの読み取りを開始する前にファイルを終了できます。cat example.txt
これは、シェルがこれらの操作を実行する順序と、cat
実際にファイルを開くのにかかる時間によって異なります。
これらの問題を完全に防ぐためにshuf example.txt > example.txt.shuf && mv example.txt.shuf example.txt
。
または一緒に行くことを選択することもできますshuf example.txt --output=example.txt
。
答え2
コンボその他のユーティリティ次のコマンドがありますsponge
。
sponge reads standard input and writes it out to the specified file.
Unlike a shell redirect, sponge soaks up all its input before opening
the output file. This allows constricting pipelines that read from and
write to the same file.
このようにして、次のことができます。
shuf example.txt | sponge example.txt
(残念ながら、moreutilsパッケージにはutilというツールもありますがparallel
、これはgnuの並列よりはるかに便利ではありません。parallel
moreutils インストールを削除しました。)
答え3
君は運が良くて走れるだけだよ
cat example.txt | shuf > example.txt
example.txt
このコマンドのように空ではありません。
shuf example.txt > example.txt
リダイレクトは、コマンドを実行し、同時にパイプラインコンポーネントを実行する前にシェルで実行されます。
-o
/オプションを使用するのが--output
最善の解決策である可能性がありますが、shuf
(非常に少し)リスクを負う場合は、処理されたファイルを読み取る前に切り捨てることを防ぐための異なる方法があります。
shuf example.txt | (sleep 1;rm example.txt;cat > example.txt)
提案してくれたOleに感謝します。この方法はより簡単で高速です。
(rm example.txt; shuf > example.txt) < example.txt
答え4
ExモードでVimを使用できます。
ex -sc '%!shuf' -cx example.txt
%
すべての行を選択!
コマンドの実行x
保存して閉じる