让我举个例子吧:
$ 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)
zshglobs 的另一个优点是您可以指定只需要常规文件(使用.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 dotglobwhich 通知 bash 在 * glob 中包含点文件。
对于 POSIX 兼容性或其他 shell 的使用,我希望其他答案有用。解决方案
亮点shopt -s dotglob: 不包括。和 .. ; 它不会以递归方式包含子目录;它很短;它可以放在 .bashrc 文件中。
| 归档时间: |
|
| 查看次数: |
4848 次 |
| 最近记录: |