2

bash guru ;) 特定のファイルで特定のキーワードの一致を grep する bash の文字列を改善しようとしています。次のようになります。

find /<path>/hp -iname '*.ppd' -print0 | xargs -0 grep "\*ModelName\:"

これは私にとって非常に高速に機能します!これより20倍高速:

find /<path>/hp -iname '*.ppd' -print0 | xargs -0 -I {} bash -c 'grep "\*ModelName\:" {}'

しかし、問題は、最初のスクリプトで次の行を取得していることです。

/<path>/hp/hp-laserjet_m9040_mfp-ps.ppd:*ModelName: "HP LaserJet M9040 M9050 MFP"

しかし、望ましい結果は

*ModelName: "HP LaserJet M9040 M9050 MFP"  

(2 番目のスクリプトのように)。どうすれば達成できますか?

PS:findスクリプトの柔軟性と将来の改善のために使用しています。

4

4 に答える 4

5

の必要はありませんfind

grep -rh --include "*.ppd" "\*ModelName\:"
于 2012-12-22T14:19:43.967 に答える
4

出力からファイル名を抑制する-hオプション。grep

find /<path>/hp -iname '*.ppd' -print0 | xargs -0 grep -h "\*ModelName\:"

あなたが使用grepを提供していない場合:-hcat

find /<path>/hp -iname '*.ppd' -print0 | xargs -0 cat | grep "\*ModelName\:"

また、参考までに、2 番目のオプションを追求したい場合に不要になるオプションをfind提供します。-execxargs

find /<path>/hp -iname '*.ppd' -exec grep grep "\*ModelName\:" '{}' \;
于 2012-12-22T13:29:29.000 に答える
1

find を完全に取り除くことができます(bashで):

shopt -s globstar
grep -h "\*ModelName\:" /<path>/hp/**.[pP][pP][dD]

巨大なディレクトリ ツリーがある場合は、少し遅くなる可能性があります (あなたの場合は疑問です)。

  • 長所: 起動されるプロセスは 1 つだけです!
  • 短所:あなたが言及した将来の改善は、実装がより困難になる可能性があります.

この場合、次を使用することをお勧めします。

find /<path>/hp -iname '*.ppd' -exec grep -h "\*ModelName\:" {} +

(+最後に注意してください: 1 つだけgrepが起動されます)。

于 2012-12-22T13:55:16.190 に答える
0

出力行を考えてください

/<path>/hp/hp-laserjet_m9040_mfp-ps.ppd:*ModelName: "HP LaserJet M9040 M9050 MFP"

コロンで区切られた 3 つのフィールドのレコードとして。出力行をこのように考える場合、最終的な回答として 3 番目のフィールドを抽出する必要があります。awkについて何も知らない場合は、以下に示すように、少なくとも特定の列セパレータを使用して出力データの列を印刷する方法を知っている必要があります。

find /<path>/hp -iname '*.ppd' -print0 | xargs -0 grep "\*ModelName\:" | awk -F:'{ print $3}'

awkについて知っておくべきもう 1 つのことは、出力データの特定の列の数値を合計する (場合によっては平均を取る) 方法ですが、それは別の日の話です :)

コマンド チェーンにawkコマンドを追加する利点は、最適化されたコマンド チェーンの高速なパフォーマンスに基づいて構築し、それを利用できることです :)

あなたの場合、答えはxargsfindawkを使用したgrepです:)

于 2014-03-12T11:46:44.387 に答える