使用grep --exclude / - include语法不要浏览某些文件

时间:2008-10-21 13:41:02

标签: unix search shell command-line grep

我在目录树的文本文件中查找字符串foo=。它在一台普通的Linux机器上,我有bash shell:

grep -ircl "foo=" *

在目录中还有许多匹配“foo =”的二进制文件。由于这些结果不相关并且减慢了搜索速度,我希望grep跳过搜索这些文件(主要是JPEG和PNG图像)。我该怎么做?

我知道有--exclude=PATTERN--include=PATTERN选项,但模式格式是什么? grep的手册页说:

--include=PATTERN     Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN     Recurse in directories skip file matching PATTERN.

grep上搜索 grep包含排除 grep exclude ,并且变体找不到任何相关内容

如果有更好的方法只在某些文件中进行grepping,我会全力以赴;移动违规文件不是一种选择。我不能只搜索某些目录(目录结构很乱,随处可见)。另外,我无法安装任何东西,因此我必须使用常用工具(例如 grep 或建议的 find )。

22 个答案:

答案 0 :(得分:693)

使用shell globbing语法:

grep pattern -r --include=\*.{cpp,h} rootdir

--exclude的语法相同。

请注意,星号会使用反斜杠进行转义,以防止它被shell展开(引用它,例如--include="*.{cpp,h}",也可以正常工作)。否则,如果当前工作目录中的任何文件与模式匹配,命令行将扩展为类似grep pattern -r --include=foo.cpp --include=bar.h rootdir的内容,该文件只会搜索名为foo.cppbar.h的文件,很可能不是你想要的。

答案 1 :(得分:211)

如果您只想跳过二进制文件,我建议您查看-I(大写i)选项。它忽略了二进制文件。我经常使用以下命令:

grep -rI --exclude-dir="\.svn" "pattern" *

它以递归方式搜索,忽略二进制文件,并且不会查看Subversion隐藏文件夹,无论我想要什么样的模式。我在工作箱上把它作为“grepsvn”别名。

答案 2 :(得分:62)

请查看专为这些情况设计的ack

的例子
grep -ircl --exclude=*.{png,jpg} "foo=" *

用ack完成

ack -icl "foo="

因为默认情况下ack永远不会查找二进制文件,并且默认情况下-r处于启用状态。如果你只想要CPP和H文件,那就做吧

ack -icl --cpp "foo="

答案 3 :(得分:34)

grep 2.5.3引入了--exclude-dir参数,该参数将按照您想要的方式工作。

grep -rI --exclude-dir=\.svn PATTERN .

您还可以设置环境变量:GREP_OPTIONS =“ - exclude-dir = .svn”

我将第二次Andy's投票给ack,但这是最好的。

答案 4 :(得分:24)

我发现这很长一段时间后,你可以添加多个包含并排除如下:

grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js

答案 5 :(得分:12)

建议的命令:

grep -Ir --exclude="*\.svn*" "pattern" *

在概念上是错误的,因为--exclude对basename起作用。换句话说,它将仅跳过当前目录中的.svn。

答案 6 :(得分:11)

在grep 2.5.1中你必须将这一行添加到〜/ .bashrc或〜/ .bash profile

export GREP_OPTIONS="--exclude=\*.svn\*"

答案 7 :(得分:9)

我发现grepping grep的输出有时非常有用:

grep -rn "foo=" . | grep -v "Binary file"

但是,这实际上并没有阻止它搜索二进制文件。

答案 8 :(得分:7)

在CentOS 6.6 / Grep 2.6.3上,我必须像这样使用它:

grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*"

请注意缺少等号" =" (否则--include--excludeinclude-dir--exclude-dir将被忽略)

答案 9 :(得分:6)

如果您不反对使用find,我喜欢其-prune功能:

find [directory] \
        -name "pattern_to_exclude" -prune \
     -o -name "another_pattern_to_exclude" -prune \
     -o -name "pattern_to_INCLUDE" -print0 \
| xargs -0 -I FILENAME grep -IR "pattern" FILENAME

在第一行,指定要搜索的目录。例如,.(当前目录)是有效路径。

在第2行和第3行,使用"*.png""*.gif""*.jpg"等。你可以使用尽可能多的-o -name "..." -prune构造。

在第4行,你需要另一个-o(它指定“或”到find),你想要的模式,你需要-print或{{1在它的最后。如果您只想修剪-print0*.gif等图像后仍然存在“其他所有内容”,请使用 *.png你完成了第4行。

最后,在第5行是-o -print0的管道,它获取每个结果文件并将它们存储在变量xargs中。然后,它会FILENAME grep个标记,-IR,然后"pattern"FILENAME扩展为xargs找到的文件名列表}。

对于您的特定问题,声明可能类似于: find

答案 10 :(得分:5)

我很认真,但这是我的〜/ .bash_profile的样子:

export GREP_OPTIONS="-orl --exclude-dir=.svn --exclude-dir=.cache --color=auto" GREP_COLOR='1;32'

请注意,要排除两个目录,我必须使用--exclude-dir两次。

答案 11 :(得分:4)

git grep

使用针对性能进行了优化的git grep,旨在搜索某些文件。

默认情况下,它会忽略二进制文件,并尊重您的.gitignore。如果您不使用Git结构,您仍然可以通过传递--no-index

来使用它

语法示例:

git grep --no-index "some_pattern"

有关更多示例,请参阅:

答案 12 :(得分:3)

试试这个:

 $ find . -name "*.txt" -type f -print | xargs file | grep "foo=" | cut -d: -f1

在这里成立:http://www.unix.com/shell-programming-scripting/42573-search-files-excluding-binary-files.html

答案 13 :(得分:3)

如果您以非递归方式搜索,则可以使用glop patterns来匹配文件名。

grep "foo" *.{html,txt}

包括html和txt。它仅在当前目录中搜索。

要在子目录中搜索:

   grep "foo" */*.{html,txt}

在子目录中:

   grep "foo" */*/*.{html,txt}

答案 14 :(得分:2)

这些脚本无法解决所有问题...请更好地尝试:

du -ha | grep -i -o "\./.*" | grep -v "\.svn\|another_file\|another_folder" | xargs grep -i -n "$1"

这个脚本更好,因为它使用“真正的”正则表达式来避免搜索目录。只需用“\ |”分隔文件夹或文件名在grep -v

上 享受吧! 在我的linux shell上找到了! XD

答案 15 :(得分:2)

看看这个。

grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags

答案 16 :(得分:2)

find和xargs是你的朋友。使用它们来过滤文件列表而不是grep的--exclude

尝试类似

的内容
find . -not -name '*.png' -o -type f -print | xargs grep -icl "foo="

答案 17 :(得分:2)

  

在目录中也有很多二进制文件。我不能只搜索某些目录(目录结构很乱)。是否有更好的方法只在某些文件中进行grepping?

ripgrep

这是用于递归搜索当前目录的最快工具之一。它以Rust编写,构建于Rust's regex engine之上,以实现最高效率。查看detailed analysis here

所以你可以跑:

rg "some_pattern"

它尊重您的.gitignore并自动跳过隐藏的文件/目录和二进制文件。

您仍然可以使用-g / --glob自定义包含或排除文件和目录。全局规则匹配.gitignore个全局。请查看man rg以获取帮助。

有关更多示例,请参阅:How to exclude some files not matching certain extensions with grep?

在macOS上,您可以通过brew install ripgrep安装。

答案 18 :(得分:1)

GNU --binary-files=without-match的{​​{1}}选项使其跳过二进制文件。 (相当于其他地方提到的grep开关。)

(这可能需要最新版本的-I; 2.5.3至少有它。)

答案 19 :(得分:1)

适合tcsh .alias文件:

alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *'

我花了一些时间才发现{mm,m,h,cc,c}部分不应该在引号内。 〜基思

答案 20 :(得分:0)

忽略来自grep的所有二进制结果

grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}'

awk部分将过滤掉所有二进制文件foo匹配行

答案 21 :(得分:-2)

试试这个:

  1. 在currdir下创建一个名为“--F”的文件夹..(或链接另一个重命名为“--F”的文件夹,即double-minus-F
  2. #> grep -i --exclude-dir="\-\-F" "pattern" *