-n が 1 より大きい場合、-I{} を -xargs' と一緒に使用するには?

-n が 1 より大きい場合、-I{} を -xargs' と一緒に使用するには?

grep特定の文字列を処理する必要がある多くのファイルがあります。ファイルの小さな部分にスペースがあります。ファイルが多すぎると、プロセス生成のオーバーヘッドは-n1実際にはファイル検索自体よりも大きくなります。

これはうまくいきますが、遅すぎるので便利ではありません。

cat filelist | xargs -I{} grep mystring '{}'

grepしたがって、次のように各インスタンスに1000個のパラメータを渡したいと思います。

cat filelist | xargs -n1000 -I{} grep mystring '{}'

しかし、これはうまくいきません。 = 1のときにのみ{}動作していると思いますか? !-n

例:

プロセスが多すぎます。正しい出力です。
$シーケンス1 10 | xargs -I{} -n1 エコー "<{}>"
<1>
<2>
<3>
<4>
<5>
<6>
<7>
<8>
<9>
<10>
多くのプロセスがあります...何ですか?
$シーケンス1 10 | xargs -I{} -n2 エコー "<{}>"
<{}>1 2
<{}>3 4
<{}> 5 6
<{}>7 8
<{}>9 10

たぶん私は代わりに使用することができると思いますfind

ベストアンサー1

はい、-I一度に1つのパラメータでのみ機能します。使用時の入力は、使用されていない場合(使用されているかどうかにかかわらず)-Iとは異なり、パラメータとして解析されます。-n

空でない各行には1つの単語があります-I{}(改行はバックスラッシュとして引用して含めることができることを除く) )。 。引用符("、、およびはまだ'sとは\異なります。)sh

それ以外の場合、-I{}単語はスペース(少なくともSPC、TAB、およびNL)で区切られ、引用符が処理されます。

比較する:

$ printf ' a "b c" \n' | xargs -n1 printf '<%s>\n'
<a>
<b c>
$ printf ' a "b c" \n' | xargs -I{} printf '<%s>\n' {}
<a b c >

IMO、xargs少し混乱しています。これを使用する信頼できる有用な唯一の方法は、GNU拡張を-0使用することです。-d

一度に複数の引数を含むコマンドを実行し、各引数に対して異なるプレースホルダを使用するには、次のことをお勧めしますsh

xargs < filelist -r -n2 sh -c 'printf "1: %s\n2: %s\n" "$1" "$2"' sh

ここでは、およびプレースホルダを使用してxargs一度に2つのパラメータを渡します(すべてのパラメータを一度に渡すを参照)。shsh"$1""$2""$@"

これが基本単語トークン化ですxargsfilelist各行に1つのファイルが含まれている場合は、GNUxargs-d '\n'

あなたの例では、次のようにする必要はgrepありません。-n-I

xargs < filelist grep mystring

その後、xargsできるだけ多くのパラメータが渡されますgrep(パラメータは最後に追加されます)。-rこのこと(GNU拡張子)なしでまるでfilelistすべて空であるかのようにすることができ、grepファイル引数(ブロックする-r)なしで実行し続けることはfilelist

-Hただし、GNUのoptionsを使用するgrepか、次のように実行できます。

xargs < filelist grep mystring /dev/null

grep一致するものが見つかった場合は、ファイル名にfilelist1つの単語しか含まれていない場合でも、常にファイル名を印刷する必要があります。

おすすめ記事