-exec+オプションを選択できることを理解していますxargsの動作を模倣します。あるフォームを他のフォームよりも好む状況はありますか?

パイプの使用を避けるためだけに、個人的には最初のフォームを好む傾向があります。は適切な最適化を行っている必要があります。正解ですか?

回答

呼び出しを連鎖させて検索することをお勧めします(一度学んだら、それが可能であることがわかりました) 、今日かもしれません)。もちろん、これはあなたが見つけたままでいる間だけ可能です。 xargsにパイプすると、スコープ外になります。

小さな例、a.lstとb.lstの2つのファイル:

cat a.lst fuddel.sh fiddel.sh cat b.lst fuddel.sh 

ここではトリックはありません-両方に「fuddel」が含まれているが、一方だけに「fiddel」が含まれているという事実。

それを知らなかったと仮定します。次の2つの条件に一致するファイルを検索します。

find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls 192097 4 -rw-r--r-- 1 stefan stefan 20 Jun 27 17:05 ./a.lst 

grepまたは別のプログラムが両方の文字列を条件として渡すための構文を知っているかもしれませんが、それは “重要ではありません。引数としてファイルを指定すると、trueまたはfalseを返すことができるすべてのプログラムをここで使用できます。grepは一般的な例にすぎません。

また、 find -exec と -ls または -delete など。削除はrm(ファイルを削除)だけでなく、rmdirも実行することに注意してください。 (ディレクトリを削除します)。

このようなチェーンは、特に指定されていない限り(つまり、-orスイッチを使用して(およびparens(マスキングが必要)))。

つまり、検索チェーンを離れることはありません。これは便利なことです。 -xargsを使用する利点はありません。ファイルの受け渡しに注意する必要があるためです。これは、見つける必要がないことです。各ファイルの受け渡しを単一の引数として自動的に処理します。

{}中括弧を見つけるためにマスキングが必要だと思われる場合は、証拠を求める私の質問に気軽にアクセスしてください。私の主張は次のとおりです。

コメント

  • この投稿により、。どうもありがとうございました!
  • " 'を使用してもメリットがありません-xargs "。'の-execの方法xargs -P4 4つのコアのうち3つがアイドル状態を維持しないようにしますか?
  • @DamianYerrick:

; "ただし、+(/プラス記号)が付いています。

回答

ファイル名をxargsに安全にパイプするには、find

オプションと、xargsには、それを読み取るための対応するオプションがあります(--nullまたは-0)。それ以外の場合、unprintabを含むファイル名名前に文字、円記号、引用符、または空白を含めると、予期しない動作が発生する可能性があります。一方、find -exec {} + POSIX find仕様に含まれています、したがって移植性があり、find -print0 | xargs -0とほぼ同じくらい安全であり、find | xargsよりも間違いなく安全です。 -print0なしでfind | xargsを実行することを絶対にしないことをお勧めします。

コメント

  • find … -exec … {} +の移植性に対する注目すべき例外は、OpenBSDです。これは、2012年にリリースされたバージョン5.1でのみこの機能を取得しました。 -print0数年の間、OpenBSDでさえ(しばらくの間その機能に抵抗しましたが)。一方、SolarisはPOSIX機能に固執するため、と-print0はありません。
  • -print0は苦痛であり、議論することはできますがxargs --delimiter "\n"は同等ではありません'私は'後者を発見した後、前者を一度も使用したことがありません。
  • ' -0が。
  • -0に加えて、GNU xargs入力がない場合にコマンドを実行しないようにするには-rが必要です。'
  • | xargs -r0 cmdのもう1つの問題は、cmd ' s stdin影響を受けます(xargsの実装に応じて、'の/dev/nullまたはパイプ。

回答

-exec ... ;フォームを使用する場合(覚えておいてくださいセミコロンをエスケープするには、「ファイル名ごとに1回コマンドを実行します。-print0 | xargs -0を使用する場合は、ファイル名ごとに複数のコマンドを実行します。必ずフォーム。1つのコマンドラインに複数のファイルを配置し、多数のファイルが含まれる場合にはるかに高速になります。

xargsは、xargs -Pを使用して複数のコマンドを並行して実行する機能です。マルチコアシステムでは、大幅な時間の節約になります。

コメント

  • つまり-P

の代わりに

xargs -PはPOSIX標準には含まれていませんが、find -exec {} +は含まれていることに注意してください。これは、移植性を求める場合に重要です。

  • @Alexiosシェルにとって特別な意味がないため、'プラス記号をエスケープする必要はありません:find /tmp/ -exec ls "{}" +は問題なく動作します。
  • もちろん、Corrent。私は' -execの後、長い間すべてをエスケープしてきました(I ' ma masochist 、'引用符を使用して{}をエスケープすることすらしません。常に、\{\}と入力します。 '質問しないでください)、すべてを今すぐエスケープする必要があるようです。
  • @Alexios:例を見つけた場合(マゾヒストであることを除く)、中かっこをマスキングすると便利です。ここでの私の質問に対する回答として提供してください-このヒントは古く、マンページに残っているだけです。 ' find /tmp/ -exec ls {} +が'機能しない例を見たことがありません。
  • 私にとって、これはSunOS4の時代に形成された筋肉の記憶です。'何年もやってきたので、bashは中括弧を逐語的に受け入れ始めました。 '中かっこがなかった場合、'使用した古いシェルの少なくとも1つがヒッシーフィットを投げたと確信しています'逃げました。
  • 回答

    パフォーマンスについて-exec … +は、「すべての作業を行う単一のツールですが、 GNUfindutilのドキュメントの一部-exec … +の効率が低下する場合があります:

    [find with -exec … +] は、xargsの一部の使用よりも効率が悪い場合があります。たとえば、xargsを使用すると、前のコマンドの実行中に新しいコマンドラインを作成したり、並行して実行するコマンドの数を指定したりできます。ただし、find ... -exec ... +構造には、移植性が広いという利点があります。 GNU findutilsは、バージョン4.2.12 [2005年1月] まで「-exec ... +」をサポートしていませんでした。この理由の1つは、いずれにせよ、すでに「-print0」アクションが実行されていることです。

    それが何を意味するのか正確にはわからなかったので、チャットで derobert は次のように説明しました:

    findはおそらく、ファイルの次のバッチを検索し続けることができます。 -exec … +は実行されていますが、実行されていません。
    find … | xargs …は実行されています。これは、検索が別のプロセスであり、保持されるためです。パイプバッファがいっぱいになるまで実行します

    (私がフォーマットします。)

    それがあります。ただし、パフォーマンスが本当に重要な場合は、現実的なベンチマークを実行するか、そのような場合にシェルを使用するかどうかを自問する必要があります。

    このサイトでは、次のようにアドバイスする方がよいと思います。 -exec … +フォームは、単純であり、他の回答に記載されている理由(たとえば、あまり考えずに奇妙なファイル名を処理する)のために、可能な限り使用してください。