私はbashを初めて使用し、xargs
の使用法を理解しようとしていますが、それはまだはっきりしていません。例えば:
history | grep ls
ここでは、履歴でコマンドls
を検索しています。このコマンドでは、xargs
を使用せず、正常に機能しました。
find /etc - name "*.txt" | xargs ls -l
私はこれです。xargs
を使用する必要がありましたが、それでも違いを理解できず、xargs
を使用する場合と使用しない場合を正しく決定できません。
質問に答えるために、あるコマンドからの出力を取得して別のコマンドへの引数として使用する必要がある場合は、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
を使用する代わりの方法があり、それらを学ぶことでより良いサービスを受けることができます。
簡単な答え:今のところxargs
は避けてください。数十または数百のスクリプトを記述したら、xargs
に戻ります。
コマンドは、パラメーター(rm bad_example
など)から入力を取得することも、stdin
から入力を取得することもできます(rm -i is_this_bad_too
の後の質問のyだけでなく、read answer
も) 。 grep
やsed
などの他のコマンドはパラメーターを検索し、パラメーターに入力が表示されない場合は、入力に切り替えます。
あなたの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
がある場合は、最初にこのコマンドのどれが最適かを確認してください。
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
xargs(1)は、NULで区切られていない入力の読み取りの場合、危険です(壊れている、悪用可能など)。
ファイル名を使用している場合は、代わりにfind
の-exec [command] {} +を使用してください。 NULで区切られた出力を取得できる場合は、xargs -0
を使用します。
xargs
なしで配管を使用すると、実際のデータが次のコマンドに送られます。一方、xargs
で配管を使用する場合、実際のデータは次のコマンドのパラメーターとして表示されます。具体的な例を挙げると、a.txt
とb.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
に渡されるためです。