Bash 如何从';查找';?

Bash 如何从';查找';?,bash,terminal,grep,find,Bash,Terminal,Grep,Find,正在尝试查找find命令的结果文件名中包含的单词/模式 例如,我有以下命令: find-名称grunfile.js,返回多个文件名 我如何在这些单词模式中进行grep 我的想法大致如下: find-名称grunfile.js | grep-rnw-e'purifycss' 但是,这不起作用。使用-exec{}+选项将作为参数找到的文件名列表传递给grep: find -name Gruntfile.js -exec grep -nw 'purifycss' {} + 这是最安全、最有效的方法,

正在尝试查找find命令的结果文件名中包含的单词/模式

例如,我有以下命令:

find-名称grunfile.js
,返回多个文件名

我如何在这些单词模式中进行grep

我的想法大致如下:

find-名称grunfile.js | grep-rnw-e'purifycss'


但是,这不起作用。

使用
-exec{}+
选项将作为参数找到的文件名列表传递给grep:

find -name Gruntfile.js -exec grep -nw 'purifycss' {} +
这是最安全、最有效的方法,因为当文件路径不“正常”(例如,包含空格)时,它不会中断。与使用
xargs
的方法一样,它还通过一次传递多个文件名来最小化对grep的调用次数

我已经删除了
-e
-r
开关,因为我认为它们在这里对您没有用处


摘自《人类发现》:

-exec命令{}+

-exec操作的这个变体在所选文件上运行指定的命令,但是命令行是通过在末尾附加每个所选文件名来构建的;命令调用的总数将远远少于匹配文件的数量


虽然这并不能严格回答您的问题,但只要您打开了globstar(
shopt-s globstar
),就可以在bash中过滤结果,如下所示:

grep something **/Gruntfile.js
我一直在虔诚地使用汤姆·费内克(Tom Fenech)使用的方法,直到我切换到zsh,它处理这些事情的能力要好得多。现在我所做的就是:

grep text **/*(.)
它通过当前目录中的所有常规文件显示文本


我认为这是一种更简洁的语法,特别是对于shell中的日常工作。

当存在太多文件,无法运行*扩展时:

$ grep -o 'xxmaj\|xxbos\|xxfld' train/* | wc -l
-bash: /bin/grep: Argument list too long
0
然后,此代码修复了“过长”问题:

$ find junk -maxdepth 1 -type f | xargs grep -o 'TVDetails\|xxmaj\|xxbos\|xxfld' 
junk/gum-.doc.out:TVDetails
junk/Zv0n.doc.out:TVDetails
$ find junk -maxdepth 1 -type f | xargs grep -o 'TVDetails\|xxmaj\|xxbos\|xxfld' | wc -l
2
当使用-p 0选项时,它在我的系统上运行得更快,也许在你的系统上也是如此:

$ /usr/bin/time -f "%E Elapsed Real Time" find train -maxdepth 1 -type f | xargs -P 0 grep -o 'TVDetails\|xxmaj\|xxbos\|xxfld' | wc -l
0:02.45 Elapsed Real Time
358
$ /usr/bin/time -f "%E Elapsed Real Time" find train -maxdepth 1 -type f | xargs grep -o 'TVDetails\|xxmaj\|xxbos\|xxfld' | wc -l
0:11.96 Elapsed Real Time
358

希望这能有所帮助。

读者可能会发现,知道您可以使用
-exec cmd\
作为较长的find表达式中的谓词。例如,假设OP希望在git中阶段匹配gruntfiles
find-name gruntile.js-exec grep-qw purifycss{}-exec git add{}+
那么
-exec{}+
做什么呢?尤其是
{}+
部分?有人可以把它添加到答案中吗?@Harvastum我在答案中添加了
man find
的一段摘录,您可以在那里阅读其余部分。
globstar
也受bash支持,是一个不错的选择。