grep 忽略以点开头的文件

Pan*_*dya 2 grep dot-files

让我举个例子吧:

$ echo Hello > file1
$ echo Hello > file2
$ echo Hello > .file3
$ grep Hello * 2>/dev/null
file1:Hello
file2:Hello
Run Code Online (Sandbox Code Playgroud)

在这里您可以看到忽略的 grep.file3.

预期结果:

$ grep Hello * 2>/dev/null
.file3:Hello
file1:Hello
file2:Hello
Run Code Online (Sandbox Code Playgroud)

在 的情况下ls,有一个参数-a告诉不要忽略以开头的条目,.但我找不到任何功能grep

那么,无论如何要告诉grep不要忽略以 开头的条目.?或者为什么grep忽略它们?

cuo*_*glm 12

*.文件名扩展中的前导句点不匹配。该规则由 POSIX 指定

使用模式匹配,它可以工作:

$ sh -c 'case . in *) echo 1;; esac'
1
Run Code Online (Sandbox Code Playgroud)

POSIXly:

find . ! -name . -prune -type f -exec grep 'pattern' /dev/null {} +
Run Code Online (Sandbox Code Playgroud)

这种方法比使用 shell globbing 更有优势。当文件太多时,您永远不会收到Argument list too long错误。


ter*_*don 9

正如其他人所说,*默认情况下,glob 不会包含隐藏文件(名称以点开头的文件)。一个简单的方法是使用两个 glob:

grep Hello * .*
Run Code Online (Sandbox Code Playgroud)

不利的一面是,除了基于 Forsyth 外壳的zsh,fish或外壳(现在,pdksh以及衍生产品,如mksh,posh或 OpenBSD sh)会导致grep抱怨搜索目录...

$ grep Hello * .*
file1:Hello
file2:Hello
grep: .: Is a directory
grep: ..: Is a directory
.file3:Hello
Run Code Online (Sandbox Code Playgroud)

您可以忽略这些错误(在这种情况下它们并不重要),或者您可以使用一个简单的循环并检查目标是否为常规文件(在符号链接解析之后):

$ for file in .* *; do [ -f "$file" ] && grep -H -- Hello "$file"; done 
.file3:Hello
file1:Hello
file2:Hello
Run Code Online (Sandbox Code Playgroud)


Sté*_*las 9

对于 globs 包含隐藏文件,除了...

使用zsh,(t)cshfish,如果 glob(s) 不匹配任何文件,则不会运行该命令。在其他 shell 中,不匹配的 glob 将按原样传递给grep,并grep会抱怨相应的文件不存在。


mur*_*uru 7

grep不会忽略任何东西。*,默认情况下,不匹配带有前导.. 如果你有 GNU grep,使用它的递归选项会更容易,而不是依赖 shell 通配符:

grep Hello . -r
Run Code Online (Sandbox Code Playgroud)


Pre*_*rem 6

其他人正确地说,*不会匹配以点开头的文件。许多答案中都给出了各种解决方案,其中大多数都有一些漏洞或其他(例如包括 . & .. ;或排除以多个点开头的文件;或包括子目录;或涉及很长的命令- line)所有这些都为这个问题提供了一些新的观点。

我的简单解决方案(对于 bash 用户)是使用shopt -s dotglobwhich 通知 bash 在 * glob 中包含点文件
对于 POSIX 兼容性或其他 shell 的使用,我希望其他答案有用。解决方案
亮点shopt -s dotglob: 不包括。和 .. ; 它不会以递归方式包含子目录;它很短;它可以放在 .bashrc 文件中。

  • 这个答案的问题:它只能在 bash 中工作。 (2认同)