web-dev-qa-db-ja.com

配管時にxargsを使用するのはいつですか?

私はbashを初めて使用し、xargsの使用法を理解しようとしていますが、それはまだはっきりしていません。例えば:

history | grep ls

ここでは、履歴でコマンドlsを検索しています。このコマンドでは、xargsを使用せず、正常に機能しました。

find /etc - name "*.txt" | xargs ls -l

私はこれです。xargsを使用する必要がありましたが、それでも違いを理解できず、xargsを使用する場合と使用しない場合を正しく決定できません。

11
Sara Hamad

質問に答えるために、あるコマンドからの出力を取得して別のコマンドへの引数として使用する必要がある場合は、xargsを使用できます。最初の例では、grepは、引数としてではなく、標準入力からデータを取得します。したがって、xargsは必要ありません。

xargsは、標準入力からデータを取得し、コマンドを実行します。デフォルトでは、データは引数としてコマンドの最後に追加されます。ただし、入力にプレースホルダーを使用して、どこにでも挿入できます。従来のプレースホルダーは{}です。これを使用すると、サンプルコマンドは次のように記述されます。

find /etc -name "*.txt" | xargs -I {} ls -l {}

/etcに3つのテキストファイルがある場合、それぞれの完全なディレクトリリストが表示されます。もちろん、ls -l /etc/*.txtを簡単に記述して、問題を回避することもできます。

別の例では、これらのファイルの名前を変更でき、プレースホルダー{}を2回使用する必要があります。

find /etc -name "*.txt" | xargs -I {} mv {} {}.bak

これらは両方とも悪い例であり、空白を含むファイル名があるとすぐに壊れます。 findにファイル名をヌル文字で区切るように指示することで、これを回避できます。

find /etc -print0 -name "*.txt" | xargs -I {} -0 mv {} {}.bak

私の個人的な意見では、ほとんどの場合、xargsを使用する代わりの方法があり、それらを学ぶことでより良いサービスを受けることができます。

10
miken32

簡単な答え:今のところxargsは避けてください。数十または数百のスクリプトを記述したら、xargsに戻ります。

コマンドは、パラメーター(rm bad_exampleなど)から入力を取得することも、stdinから入力を取得することもできます(rm -i is_this_bad_tooの後の質問のyだけでなく、read answerも) 。 grepsedなどの他のコマンドはパラメーターを検索し、パラメーターに入力が表示されない場合は、入力に切り替えます。
あなたのgrepの例は、stdinからの読み取りでうまく機能し、特別なことは何も必要ありません。
lsには、パラメータとしてfindの出力が必要です。 xargsは、状況を好転させる1つの方法にすぎません。 xargsの詳細については、man xargsを使用してください。代替案:

find /etc -name "*.txt" -exec ls -l {} \;
find /etc -name "*.txt" -ls
ls -l $(find /etc -name "*.txt" )
ls /etc/*.txt

/ etcにa nasty filename with spaces.txtがある場合は、最初にこのコマンドのどれが最適かを確認してください。

3
Walter A

GNU Parallelはxargsと同じことを行うことができますが、壊れた悪用可能な「機能」はありません。

GNU Parallelは、例を見て学ぶことができます http://www.gnu.org/software/parallel/man.html#EXAMPLE:-Working-as-xargs-- n1.-Argument-appending そしてチュートリアルをウォークスルー http://www.gnu.org/software/parallel/parallel_tutorial.html

0
Ole Tange

xargs(1)は、NULで区切られていない入力の読み取りの場合、危険です(壊れている、悪用可能など)。

ファイル名を使用している場合は、代わりにfindの-​​exec [command] {} +を使用してください。 NULで区切られた出力を取得できる場合は、xargs -0を使用します。

0
Rany Albeg Wein

xargsなしで配管を使用すると、実際のデータが次のコマンドに送られます。一方、xargsで配管を使用する場合、実際のデータは次のコマンドのパラメーターとして表示されます。具体的な例を挙げると、a.txtb.txtのあるフォルダーがあるとします。 a.txtには1行だけが含まれています 'hello world!'、およびb.txtは空です。

もしあなたがそうするなら

ls | grep txt

最終的に出力を取得することになります。

a.txt
b.txt

しかし、あなたがそうするなら

ls | xargs grep txt

ファイルa.txtもb.txtにもWord txtが含まれていないため、何も取得されません。コマンドが

ls | xargs grep hello

あなたは得るだろう

hello world!

これは、xargsを使用すると、lsで指定された2つのファイル名が実際のコンテンツではなく引数としてgrepに渡されるためです。

0
Nothing More