2

bash guru ;) 我正在尝试改进 bash 中的一些字符串,这些字符串在特定文件中 grep 特定关键字的匹配项。它看起来像这样:

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"  

(如在第二个脚本中)。我怎样才能实现它?

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不提供-h使用cat

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

此外,为了您的信息,如果您想追求第二个选项,请find提供-exec将变得不必要的选项:xargs

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]

如果你有一个巨大的目录树(我怀疑你的情况),可能会慢一点。

  • 亲:只启动了一个进程!
  • 缺点:您提到的未来改进可能更难以实施。

在这种情况下,您最好使用:

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

(注意+最后:只会grep启动一个)。

于 2012-12-22T13:55:16.190 回答
0

想想你的输出线

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

作为由冒号分隔的三个字段的记录。如果您以这种方式考虑输出行,那么您希望提取第三个字段作为最终答案。如果您对awk一无所知,您至少应该知道如何使用特定的列分隔符打印一列输出数据,如下所示:

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

关于awk ,您应该了解的另一件事是如何总结(偶尔取平均值)特定输出数据列中的数字,但这是另一回事了 :)

将awk命令附加到命令链的优势在于,您正在构建并利用优化命令链的快速性能:)

在您的情况下,答案是grepxargsfindawk :)

于 2014-03-12T11:46:44.387 回答