grep 忽略以点开头的文件

grep 忽略以点开头的文件

让我举个例子吧:

$ echo Hello > file1
$ echo Hello > file2
$ echo Hello > .file3
$ grep Hello * 2>/dev/null
file1:Hello
file2:Hello

在这里你可以看到 grep 被忽略,.file3它是从.

预期结果:

$ grep Hello * 2>/dev/null
.file3:Hello
file1:Hello
file2:Hello

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

那么,有没有办法告诉grep不要忽略以 开头的条目.?或者为什么grep忽略它们?

答案1

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

通过模式匹配,它可以工作:

$ sh -c 'case . in *) echo 1;; esac'
1

POSIXly:

find . ! -name . -prune -type f -exec grep 'pattern' /dev/null {} +

这种方法比使用 shell 通配符具有优势。你永远不会得到参数列表太长文件太多时出错。

答案2

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

grep Hello * .*

不利的一面是,除了基于 Forsyth shell 的zsh,或 shell(现在还有,或 OpenBSD 之类的衍生产品),这会导致在搜索目录和时抱怨:fishpdkshmkshposhshgrep...

$ grep Hello * .*
file1:Hello
file2:Hello
grep: .: Is a directory
grep: ..: Is a directory
.file3:Hello

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

$ for file in .* *; do [ -f "$file" ] && grep -H -- Hello "$file"; done 
.file3:Hello
file1:Hello
file2:Hello

答案3

对于包含除.和 之外的隐藏文件的 glob ..

  • zsh:

    grep Hello ./*(D)
    

    (您还需要./以 开头的文件名-)。或者:

    (set -o dotglob; grep Hello ./*)
    

    glob的另一个优点zsh是您可以指定只需要常规文件(使用.glob 限定符):

    grep Hello ./*(D.)
    
  • ksh93:

    (FIGNORE='.?(.)'; grep Hello ./*)
    
  • bash:

    (shopt -s dotglob; grep Hello ./*)
    
  • tcsh:

    (set globdot; grep Hello ./*)
    
  • fish:

    grep Hello {.,}*
    
  • Forsyth shell 及其衍生产品(pdksh、OpenBSD sh、、posh... mksh)以及fish

    grep Hello ./.* ./*
    
  • rc, es:

    grep Hello ./.[~.]* ./..?* ./*
    
  • Bourne shell、ksh88 和 Almquist shell 衍生物:

    grep Hello ./.[!.]* ./..?* ./*
    
  • csh:

    grep Hello ./.[^.]* ./..?* ./*
    

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

答案4

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

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

相关内容