@Alex Gitelman の回答を拡張するには:はい、「標準入力」とコマンド ラインには違いがあります。
rm a.txt b.txt c.txt
と入力すると 、 rm
の後にリストするファイル 引数として知られています 特別な変数 (argv
と呼ばれる) を介して rm で使用できるようになります。 初めの)。一方、標準入力は、stdin
という名前のファイルのような Unix プログラムを参照します。 .プログラムは、ディスク上の通常のファイルを開いてそこから読み取る場合と同様に、この「ファイル」からデータを読み取ることができます。
rm
は、他の多くのプログラムと同様に、コマンド ラインから引数を取りますが、標準入力は無視します。好きなように何でもパイプできます。そのデータを捨てるだけです。そこが xargs
です 重宝します。標準入力の行を読み取り、それらをコマンドライン引数に変換するため、データを別のプログラムのコマンドラインに効果的にパイプできます。巧妙なトリックです。
例:
find . -name ".txt" | xargs rm
find . -name ".txt" | grep "foo" | xargs rm
改行またはスペースを含むファイル名がある場合、これは正しく機能しないことに注意してください。改行またはスペースを含むファイル名を処理するには、代わりに使用する必要があります:
find . -name ".txt" -print0 | xargs -0 rm
これは find
を教えてくれます 改行の代わりに null 文字で結果を終了します。ただし、grep
それまでのようには機能しません。代わりにこれを使用してください:
find . -name ".txt" | grep "foo" | tr "\n" "\0" | xargs -0 rm
今回は tr
すべての改行をヌル文字に変換するために使用されます。
「検索結果を rm にパイプできないのはなぜですか?」
何かをプログラムにパイプすると、パイプがキーボード入力を置き換えます。これを念頭に置いて、次の質問を自問してください:rm
は何でしょう? キーボードでやる?キーストロークを削除しますか? (確かに少しばかげています)インタラクティブなコントロールを受け入れますか? (rm
確認が必要な場合を除き、対話型ではありません。確認は実際にパイプで行うことができます。)
実際のところ、 rm
の場合 は既に実行されているため、コマンドを入力してファイルを削除することはできません....そのため、パイプでもそれを行うことはできません.
パイプがキーボードと画面の組み合わせを置き換えることを心に留めておけば、物事はすぐにより論理的に見えます。
今は逆です。データストリームを grep
にパイプできます .それは、grep にキーボードからのキーストロークを代わりに入力データとして読み取らせることができるということですか?
はい!これは、実際に (パイピングなしで) ネイティブに行うことです。
(ところで、検索引数を grep
にパイプしたり入力したりできないことに注意してください )
これで、できない理由がわかりました パイプを rm におよび コマンドライン引数として機能することを期待してください。
tl;dr:
UNIX 哲学に基づくプログラムの構造:
ファイル イン、ファイル アウト、キーボード イン、スクリーン アウト。 -> パイプはキーボードとスクリーンを置き換えるだけです。
パイプは、最初のコマンドの出力を 2 番目の標準入力に送信します。 rm
標準入力を受け入れないため、パイプできません。 xargs
を使用できます xargs
の例を見つけることができます。 具体的には、xargs のマニュアル ページに記載されています。