我想./test/main.cpp
从搜索中排除文件。
这是我所看到的:
$ grep -r pattern --exclude=./test/main.cpp
./test/main.cpp:pattern
./lib/main.cpp:pattern
./src/main.cpp:pattern
我知道可以通过在管道和过滤器布置中使用多个命令来获得所需的输出,但是是否有一些引号/转义符可以使grep
我理解本机?
我想./test/main.cpp
从搜索中排除文件。
这是我所看到的:
$ grep -r pattern --exclude=./test/main.cpp
./test/main.cpp:pattern
./lib/main.cpp:pattern
./src/main.cpp:pattern
我知道可以通过在管道和过滤器布置中使用多个命令来获得所需的输出,但是是否有一些引号/转义符可以使grep
我理解本机?
Answers:
grep
如果您在不同目录中有更多具有相同名称的文件,则无法对某个目录中的文件执行此操作,请改用find:
find . -type f \! -path './test/main.cpp' -exec grep pattern {} \+
\!
和\+
?没有反斜杠,它似乎工作正常。
grep
无法做到,find
取而代之” –完美。
我认为GNU不可能实现grep
。您虽然不需要管道。
与find
:
find . ! -path ./test/main.cpp -type f -exec grep pattern {} +
与zsh
:
grep pattern ./**/*~./test/main.cpp(.)
(排除隐藏文件,以及排除.git,.svn ...)。
我可以写一本书:“迷失的艺术xargs
”。在find ... -exec … ';
启动为每个文件的grep(但与变异-exec … +
没有)。好吧,这些天我们在浪费CPU周期,为什么不呢?但是,如果性能,内存和功耗是一个问题,请使用xargs:
find . -type f \! -path 'EXCLUDE-FILE' -print0 | xargs -r0 grep 'PATTERN'
GNU的find
- -print0
将NUL
终止其输出,xargs
' -0
选项将采用该格式作为输入。这样可以确保文件中包含任何有趣的字符,管道都不会混淆。该-r
选项确保万一find
没有发现任何错误。
注意,您现在可以执行以下操作:
find . -type f -print0 | grep -z -v "FILENAME EXCLUDE PATTERN" |
xargs -r0 grep 'PATTERN'
GNU grep的-z
功能与xargs 的功能相同-0
。
find -exec (cmd) {} +
的工作方式相同xargs
且find -exec (cmd) {} \;
工作方式相同xargs -n1
。换句话说,只有\;
使用版本,您的陈述才是正确的。
xargs
效率比使用效率低-exec … +
(尽管是有限的)。这里没有答案甚至都没有提到-exec … \;
。
-exec ... +
是在2005年1月添加的。是的,我并没有过时。
如果您的find
支持-path
在2008年添加到POSIX,但是在Solaris中仍然缺少:
find . ! -path ./test/main.cpp -type f -exec grep pattern /dev/null {} +
-path
不是POSIX?
作为记录,这是我更喜欢的方法:
grep pattern $(find . -type f ! -path './test/main.cpp')
通过grep
在命令开始处保留,我认为这会更清楚-而且它不会禁用grep
的颜色突出显示。从某种意义上说,find
在命令替换中使用只是扩展/替换功能的(受限)文件搜索子集的一种方式grep
。
对我来说,find -exec
语法有点奥秘。一种复杂性find -exec
是(有时)需要转义各种字符(尤其\;
是在Bash下使用时)。仅出于将事物放入熟悉的上下文的目的,以下两个命令基本上是等效的:
find . ! -path ./test/main.cpp -type f -exec grep pattern {} +
find . ! -path ./test/main.cpp -type f -print0 |xargs -0 grep pattern
如果要排除子目录,则可能需要使用通配符。我在这里不完全了解架构- 谈论arcane:
grep pattern $(find . -type f ! -path './test/main.cpp' ! -path './lib/*' )
进一步概述在脚本中使用的find
基于解决方案的注意事项:命令行应包含/ 选项。否则,在的搜索结果中碰巧只有一个文件名的情况下,它将更改输出格式。值得注意的是,如果使用的本机文件搜索(带有选项),则似乎没有必要。grep
-H
--with-filename
find
grep
-r
...更好的是,将其/dev/null
作为第一个文件进行搜索。这解决了两个问题:
grep
将认为有两个文件并使用多文件输出模式。grep
将认为只有一个文件并且不会在stdin上挂起。因此,最终答案是:
grep pattern /dev/null $(find . -type f ! -path './test/main.cpp')
find
在命令替换中使用输出。如果文件名包含空格或其他特殊字符,则此操作会中断。使用find -exec
,功能强大且易于使用。
find -iname "*target*" -or -name 'exclude' -prune
。好吧,这很有效-修剪后的目录将被列出,但不会被搜索。如果您不想将其列出,则可以添加一些多余的内容! -name 'exclude'
--exclude-dir
),则会放大该问题。这就是为什么我想让grep在本地执行排除。