回答:
違いは、ターゲットプログラムが受け入れるデータにあります。
パイプを使用するだけの場合、STDIN(標準入力ストリーム)のデータを、一度に1行ずつソートできる生のデータの山として受け取ります。ただし、一部のプログラムは標準入力でコマンドを受け入れません。コマンドへの引数にスペルが記述されていることを期待しています。たとえばtouch、コマンドラインのパラメーターとしてファイル名を次のように使用しますtouch file1.txt。
あなたはファイル名を出力するプログラムがある場合は、標準出力には、それらを使用する引数としてのtouch、あなたが使用する必要がありxargsSTDINストリームデータを読み込み、コマンドにスペースで区切られた引数に各行を変換します。
これら2つのことは同等です。
# touch file1.txt
# echo file1.txt | xargs touch
xargs何をしているのか、なぜそれが必要なのかを正確に知っていない限り、使用しないでください。xargs変換を強制するために使用するよりも、ジョブを実行するためのより良い方法がある場合が非常によくあります。変換プロセスには、エスケープや単語拡張などの潜在的な落とし穴もあります。
xargs -0)。これはと組み合わせて使用すると便利ですfind -print0。
xargsスペースで区切られた引数を使用してシェル経由でプログラムを呼び出しますか、それとも実際に引数リストを内部で構築しますか(例:execv/ で使用するためexecp)?
-d \nが、BSD xargs(OSXなど)はこのオプションをサポートしていないようです。
既に提供されている答えを拡張するために、xargs今日のマルチコアおよび分散コンピューティング環境でますます重要になっているクールなことができます。ジョブを並列処理できます。
例えば:
$ find . -type f -name '*.wav' -print0 |xargs -0 -P 3 -n 1 flac -V8
一度に3つのプロセスを使用して、*。wav => * .flacをエンコードします(-P 3)。
-execパラメーターはジョブを並列処理しません。
-0引数をxargsNULL入力文字の区切り文字と見なすことに注意してください。find -print0NULLで区切られたアイテムを出力します。これは、スペース、引用符、またはその他の特殊文字が含まれる可能性のあるファイル名には最適です。
xargsは、stdinにファイルパスのリストがあり、それらを使用して何かをしたい場合に特に便利です。例えば:
$ git ls-files "*.tex" | xargs -n 1 sed -i "s/color/colour/g"
この手順をステップごとに調べてみましょう。
$ git ls-files "*.tex"
tex/ch1/intro.tex
tex/ch1/motivation.tex
....
言い換えれば、入力は何かをしたいパスのリストです。
これらのパスでxargsが何を行うかを調べるには、次のechoようにコマンドの前に追加するのが良い方法です。
$ git ls-files "*.tex" | xargs -n 1 echo sed -i "s/color/colour/g"
sed -i "s/color/colour/g" tex/ch1/intro.tex
sed -i "s/color/colour/g" tex/ch1/motivation.tex
....
-n 1引数はxargsのは、独自のコマンドに各ラインを回すようになります。sed -i "s/color/colour/g"このコマンドは、すべての出現置き換えますcolorとをcolour指定したファイルのため。
これは、パスにスペースがない場合にのみ機能することに注意してください。その場合、-0フラグを渡すことにより、nargで終了したパスをxargsへの入力として使用する必要があります。使用例は次のとおりです。
$ git ls-files -z "*.tex" | xargs -0 -n 1 sed -i "s/color/colour/g"
これは上で説明したものと同じですが、パスの1つにスペースが含まれている場合にも機能します。
これは、findまたはなどの出力としてファイル名を生成するコマンドで機能しますlocate。ただし、多くのファイルを含むgitリポジトリで使用する場合git grep -lはgit ls-files、次のように使用する方が効率的です。
$ git grep -l "color" "*.tex" | xargs -n 1 sed -i "s/color/colour/g"
このgit grep -l "color" "*.tex"コマンドは、フレーズ「color」を含む「* .tex」ファイルのリストを提供します。
最初の引数は、違いを非常によく示しています。
\ls | grep Cases | lesslsおよびで作成されたファイル名のリストを参照できますgrep。それらがファイル名であることは問題ではなく、単なるテキストです。
\ls | grep Cases | xargs lessコマンドの最初の部分で作成された名前のファイルを参照できます。xargs入力としてファイル名のリストを受け取り、コマンドラインでコマンドを受け取り、コマンドラインでファイル名を使用してコマンドを実行します。
の使用を検討する際xargsには、入力が奇妙な方法でフォーマットされることを想定してください:ホワイトスペース区切り、with \、'および"引用に使用されます(引用\内では特別ではないため、異常な方法で)。xargsファイル名に空白やが含まれていない場合にのみ使用してください\'"。
xargsする-0, --nullオプションがあります(私はあなたからそれを学んだ可能性が非常に高いです:)。したがって、あなたはノーオプションxargコールを参照していると思いますが、引用への参照に戸惑っています。それに関するリンクや例はありますか?..(ps。| xargs lessは便利な「トリック」+1 ..ありがとう..
あなたの例xargsでは、findあなたがやりたいことを正確かつ安全に行うので、まったく使用する必要はありません。
正確に使用したいものfindは次のとおりです。
find -maxdepth 1 -name '*Cases*' -exec touch {} +
この例で-maxdepth 1は、現在のディレクトリでのみ検索し、サブディレクトリに降りないでください。デフォルトでは、findは、maxdepthで制約しない限り、すべてのサブディレクトリ(多くの場合、必要なもの)を検索します。{}その場所に置換し、取得するファイルの名前である+2つのエンドのコマンドマーカーの一つ、他のされています;。それらの違いは、;各ファイルに対して+コマンドを一度に1つずつ実行することを意味しますが、すべてのファイルに対してコマンドを一度に実行することを意味します。ただし、シェルはおそらく;それ自体を解釈しようとするため、\;またはのいずれかでエスケープする必要があることに注意してください';'。はい、findこのようないくつかの小さな迷惑がありますが、そのパワーはそれを補う以上のものです。
両方ともfind、xargs最初は学ぶのが難しいです。学習しやすくするために、xargs実行しようとしているコマンドを表示する-por --interactiveオプションを使用してみて、実行するかどうかを確認してください。
同様に、代わりにをfind使用-okして-exec、コマンドを実行するかどうかを確認できます。
ただし、find必要なことをすべて実行できない場合がありますxargs。-execコマンドが表示されるのは1つのインスタンスのみ{}であるfind -type f -exec cp {} {}.bak \;ため、エラーが発生する場合は、次のようにします。 :find -type f -print0 | xargs -0 -l1 -IX cp X X.bak
GNU FindutilsマニュアルでRun Commandsの詳細を学ぶことができます。
また、findファイルを処理しているときにスペースやその他の文字に遭遇xargsするため、代わりにnull文字で終了する入力項目を生成する何かと一緒に-0or --nullオプションを使用しない限り、あなたが望むことを安全に行うと述べました空白の。
'またはなどの"問題が発生する可能性がありますが、findこれらのケースは問題なく処理されます。
xargs(と一緒にfind、sort、du、uniq、perlおよびいくつかの他)「STDINはNUL(0×00)バイトで区切られ、ファイルのリストを持っている」と言って、コマンドラインスイッチを受け付けます。これにより、スペースやその他の面白い文字を含むファイル名を簡単に処理できます。ファイル名にはNULは含まれません。
xargsおよび$(...))にストリームを取得する2つの一般的なオプションのうち、xargsはコマンド置換よりもはるかに安全です。そして、改行を含む正当なファイル名に出くわしたことを思い出せません。エスケープと単語拡張の落とし穴は、xargsではなくコマンド置換の問題ではありませんか?