回答:
違いは、ターゲットプログラムが受け入れるデータにあります。
パイプを使用するだけの場合、STDIN(標準入力ストリーム)のデータを、一度に1行ずつソートできる生のデータの山として受け取ります。ただし、一部のプログラムは標準入力でコマンドを受け入れません。コマンドへの引数にスペルが記述されていることを期待しています。たとえばtouch
、コマンドラインのパラメーターとしてファイル名を次のように使用しますtouch file1.txt
。
あなたはファイル名を出力するプログラムがある場合は、標準出力には、それらを使用する引数としてのtouch
、あなたが使用する必要がありxargs
STDINストリームデータを読み込み、コマンドにスペースで区切られた引数に各行を変換します。
これら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
引数をxargs
NULL
入力文字の区切り文字と見なすことに注意してください。find -print0
NULLで区切られたアイテムを出力します。これは、スペース、引用符、またはその他の特殊文字が含まれる可能性のあるファイル名には最適です。
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 | less
ls
およびで作成されたファイル名のリストを参照できます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
実行しようとしているコマンドを表示する-p
or --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文字で終了する入力項目を生成する何かと一緒に-0
or --null
オプションを使用しない限り、あなたが望むことを安全に行うと述べました空白の。
'
またはなどの"
問題が発生する可能性がありますが、find
これらのケースは問題なく処理されます。
xargs
(と一緒にfind
、sort
、du
、uniq
、perl
およびいくつかの他)「STDINはNUL(0×00)バイトで区切られ、ファイルのリストを持っている」と言って、コマンドラインスイッチを受け付けます。これにより、スペースやその他の面白い文字を含むファイル名を簡単に処理できます。ファイル名にはNULは含まれません。
xargs
および$(...)
)にストリームを取得する2つの一般的なオプションのうち、xargsはコマンド置換よりもはるかに安全です。そして、改行を含む正当なファイル名に出くわしたことを思い出せません。エスケープと単語拡張の落とし穴は、xargsではなくコマンド置換の問題ではありませんか?