我在目录树的文本文件中查找字符串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 )。
答案 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.cpp
和bar.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”
答案 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
,--exclude
,include-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)
试试这个:
--F
”的文件夹..(或链接另一个重命名为“--F
”的文件夹,即double-minus-F
。#> grep -i --exclude-dir="\-\-F" "pattern" *