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 includegrep include excludegrep 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 ,-- --excludeinclude-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两次。



请看看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}部分不应放在引号内。 〜基思





grep