让我举个例子吧:
$ 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错误。
正如其他人所说,*
默认情况下,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)
对于 globs 包含隐藏文件,除了.
和..
:
zsh
:
grep Hello ./*(D)
Run Code Online (Sandbox Code Playgroud)
(您还需要./
以 开头的文件名-
)。或者:
(set -o dotglob; grep Hello ./*)
Run Code Online (Sandbox Code Playgroud)
zsh
globs 的另一个优点是您可以指定只需要常规文件(使用.
glob 限定符):
grep Hello ./*(D.)
Run Code Online (Sandbox Code Playgroud)ksh93
:
(FIGNORE='.?(.)'; grep Hello ./*)
Run Code Online (Sandbox Code Playgroud)bash
:
(shopt -s dotglob; grep Hello ./*)
Run Code Online (Sandbox Code Playgroud)tcsh
:
(set globdot; grep Hello ./*)
Run Code Online (Sandbox Code Playgroud)fish
:
grep Hello {.,}*
Run Code Online (Sandbox Code Playgroud)Forsyth shell 和衍生产品 ( pdksh
, OpenBSD sh
, posh
, mksh
...) 和fish
:
grep Hello ./.* ./*
Run Code Online (Sandbox Code Playgroud)rc
,es
:
grep Hello ./.[~.]* ./..?* ./*
Run Code Online (Sandbox Code Playgroud)Bourne shell、ksh88 和 Almquist shell 衍生物:
grep Hello ./.[!.]* ./..?* ./*
Run Code Online (Sandbox Code Playgroud)csh
:
grep Hello ./.[^.]* ./..?* ./*
Run Code Online (Sandbox Code Playgroud)使用zsh
,(t)csh
和fish
,如果 glob(s) 不匹配任何文件,则不会运行该命令。在其他 shell 中,不匹配的 glob 将按原样传递给grep
,并grep
会抱怨相应的文件不存在。
grep
不会忽略任何东西。*
,默认情况下,不匹配带有前导.
. 如果你有 GNU grep,使用它的递归选项会更容易,而不是依赖 shell 通配符:
grep Hello . -r
Run Code Online (Sandbox Code Playgroud)
其他人正确地说,*
不会匹配以点开头的文件。许多答案中都给出了各种解决方案,其中大多数都有一些漏洞或其他(例如包括 . & .. ;或排除以多个点开头的文件;或包括子目录;或涉及很长的命令- line)所有这些都为这个问题提供了一些新的观点。
我的简单解决方案(对于 bash 用户)是使用shopt -s dotglob
which 通知 bash 在 * glob 中包含点文件。
对于 POSIX 兼容性或其他 shell 的使用,我希望其他答案有用。解决方案
亮点shopt -s dotglob
: 不包括。和 .. ; 它不会以递归方式包含子目录;它很短;它可以放在 .bashrc 文件中。