bash 用 xargs grep 一些东西并找到
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/14003207/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
grep something with xargs and find
提问by likern
bash guru ;) I'm trying to improve some string in bash which grep specific keyword's matches in specific files. It looks like that:
bash guru ;) 我正在尝试改进 bash 中的一些字符串,这些字符串在特定文件中 grep 特定关键字的匹配项。它看起来像这样:
find /<path>/hp -iname '*.ppd' -print0 | xargs -0 grep "\*ModelName\:"
which works very fast for me! In 20 times faster than this one:
这对我来说非常快!比这个快 20 倍:
find /<path>/hp -iname '*.ppd' -print0 | xargs -0 -I {} bash -c 'grep "\*ModelName\:" {}'
But the problem is that in the first script I'm getting the following lines:
但问题是在第一个脚本中我得到以下几行:
/<path>/hp/hp-laserjet_m9040_mfp-ps.ppd:*ModelName: "HP LaserJet M9040 M9050 MFP"
but desired result is just
但想要的结果只是
*ModelName: "HP LaserJet M9040 M9050 MFP"  
(as in the second script). How can I achieve it?
(如在第二个脚本中)。我怎样才能实现它?
P.S.: I'm using findfor flexibility and future improvements of the script.
PS:我正在使用find脚本的灵活性和未来的改进。
回答by Chris Seymour
No need for find:
不需要find:
grep -rh --include "*.ppd" "\*ModelName\:"
回答by kmkaplan
The -hoption to grepsuppress filenames from the output.
从输出中抑制文件名的-h选项grep。
find /<path>/hp -iname '*.ppd' -print0 | xargs -0 grep -h "\*ModelName\:"
If your grepdoes not provide -hthe use cat:
如果您grep不提供-h使用cat:
find /<path>/hp -iname '*.ppd' -print0 | xargs -0 cat | grep "\*ModelName\:"
Also, for your information, findprovides the -execoption which would render xargsunnecessary had you wanted to pursue your second option:
此外,供您参考,如果您想追求第二个选项,则find提供不必要的选项:-execxargs
find /<path>/hp -iname '*.ppd' -exec grep grep "\*ModelName\:" '{}' \;
回答by gniourf_gniourf
You can get rid of find altogether (in bash):
您可以完全摆脱 find (在 bash 中):
shopt -s globstar
grep -h "\*ModelName\:" /<path>/hp/**.[pP][pP][dD]
Might be a bit slower if you have a hugedirectory tree (which I doubt in your case).
如果你有一个巨大的目录树(我怀疑你的情况),可能会慢一点。
- Pro: only one process launched!
- Con: the future improvement you mentioned might be more difficult to implement.
- 亲:只启动了一个进程!
- 缺点:你提到的未来改进可能更难实施。
In this case, you'd better use:
在这种情况下,你最好使用:
find /<path>/hp -iname '*.ppd' -exec grep -h "\*ModelName\:" {} +
(observe the +at the end: only one grepwill be launched).
(注意+最后:只会grep启动一个)。
回答by Vietnhi Phuvan
Think of your output line
想想你的输出线
/<path>/hp/hp-laserjet_m9040_mfp-ps.ppd:*ModelName: "HP LaserJet M9040 M9050 MFP"
as a record of three fields separated by a colon. If you think of your output line this way, then you want to extract the third field as your final answer. If you don't know anything about awk, you should know at least how to print a column of output data using a specific column separator, as I am showing you below:
作为由冒号分隔的三个字段的记录。如果您以这种方式考虑您的输出行,那么您希望提取第三个字段作为您的最终答案。如果您对awk一无所知,您至少应该知道如何使用特定的列分隔符打印输出数据列,如下所示:
find /<path>/hp -iname '*.ppd' -print0 | xargs -0 grep "\*ModelName\:" | awk -F:'{ print }'
The other thing you should know about awkis how to sum up (and occasionally, take the average) of the numbers in a specific column of output data, but that's another story for another day :)
关于awk,您应该了解的另一件事是如何对特定输出数据列中的数字求和(偶尔取平均值),但那是另一天的故事了:)
The advantage of appending the awkcommand to your command chain is that the you are building on and taking advantage of the fast performance of your optimized command chain :)
将awk命令附加到您的命令链的优势在于您正在构建并利用优化命令链的快速性能:)
In your case, the answer is grepwith xargsand findand awk:)
在你的情况下,答案是grepwith xargs和find和awk:)

