unix - grep命令教程 - shell grep
使用grep--exclude/- 包含语法不通过某些文件grep (15)
我正在寻找目录树中文本文件中的字符串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 include , grep include exclude , grep exclude和variants找不到任何相关的东西
如果只有在某些文件中有更好的方法,我完全赞成; 移动违规文件不是一种选择。 我不能只搜索某些目录(目录结构是一团糟,到处都是)。 另外,我无法安装任何东西,所以我必须使用常用工具(如grep或建议的查找 )。
在目录中也有许多二进制文件。 我不能只搜索某些目录(目录结构很混乱)。 只有在某些文件中有更好的方法才能进行grepping?
ripgrep
这是设计用于递归搜索当前目录的最快捷的工具之一。 它被写入Rust ,构建于Rust的正则表达式引擎之上,以实现最高效率。 在这里查看详细分析 。
所以你可以运行:
rg "some_pattern"
它尊重你的.gitignore
并自动跳过隐藏的文件/目录和二进制文件。
您仍然可以使用-g
/ --glob
自定义包含或排除文件和目录。 Globbing规则匹配.gitignore
globs。 检查man rg
寻求帮助。
在macOS上,您可以通过brew install ripgrep
进行brew install ripgrep
。
git grep
使用针对性能进行了优化的git grep
,旨在搜索某些文件。
默认情况下,它会忽略二进制文件,它正在履行您的.gitignore
。 如果你不使用Git结构,你仍然可以通过传递--no-index
来使用它。
示例语法:
git grep --no-index "some_pattern"
要仍然排除某些文件,请参阅: 如何从git grep搜索中排除某些目录/文件 。
grep 2.5.3引入了--exclude-dir参数,它将以您想要的方式工作。
grep -rI --exclude-dir=\.svn PATTERN .
你也可以设置一个环境变量:GREP_OPTIONS =“ - exclude-dir = .svn”
我会第二次参加投票,但这是最好的。
--binary-files=without-match
选项让GNU grep
可以跳过二进制文件。 (相当于其他地方提到的-I
开关。)
(这可能需要最近的grep
版本;至少2.5.3版本。)
在CentOS 6.6 / Grep 2.6.3上,我必须像这样使用它:
grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*"
注意缺少等号“=”(否则--include
,-- --exclude
, include-dir
和--exclude-dir
被忽略)
在grep 2.5.1中,您必须将此行添加到〜/ .bashrc或〜/ .bash配置文件中
export GREP_OPTIONS="--exclude=\*.svn\*"
如果你只是想跳过二进制文件,我建议你看看-I
(大写字母i)选项。 它忽略了二进制文件。 我经常使用以下命令:
grep -rI --exclude-dir="\.svn" "pattern" *
它会递归搜索,忽略二进制文件,并且不会查看Subversion隐藏文件夹,无论我想要什么样的模式。 我的工作箱上有“grepsvn”的别名。
如果您以非递归方式搜索,则可以使用glop模式来匹配文件名。
grep "foo" *.{html,txt}
包括html和txt。 它仅在当前目录中进行搜索。
要在子目录中搜索:
grep "foo" */*.{html,txt}
在子目录中:
grep "foo" */*/*.{html,txt}
建议的命令:
grep -Ir --exclude="*\.svn*" "pattern" *
在概念上是错误的,因为--exclude在基本名称上起作用。 换句话说,它只会跳过当前目录中的.svn。
忽略来自grep的所有二进制结果
grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}'
awk部分将过滤掉所有的二进制文件foo匹配行
我在很长一段时间后发现这一点,你可以添加多个包含和排除像:
grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js
我是一个dilettante,理所当然,但我的〜/ .bash_profile的外观如下:
export GREP_OPTIONS="-orl --exclude-dir=.svn --exclude-dir=.cache --color=auto" GREP_COLOR='1;32'
请注意,要排除两个目录,我必须使用--exclude-dir两次。
试试这个:
$ 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 : http://www.unix.com/shell-programming-scripting/42573-search-files-excluding-binary-files.html
请看看ack ,这是专为这些情况而设计的。 你的例子
grep -ircl --exclude=*.{png,jpg} "foo=" *
用ack完成
ack -icl "foo="
因为默认情况下,ack从不查找二进制文件,-r默认为打开。 如果你只想要CPP和H文件,那么就做
ack -icl --cpp "foo="
适用于tcsh .alias文件:
alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *'
花了我一段时间才发现{mm,m,h,cc,c}部分不应放在引号内。 〜基思