如何对目录中的所有文件非递归地使用 grep?

如何对目录中的所有文件非递归地使用 grep?

我想在目录中的所有文件中搜索一串文本(而不是它的子目录;我知道该-r选项可以做到这一点,但这不是我想要的)。

  1. 跑步

    grep "string" /path/to/dir
    

    应该可以做到这一点,我已经读过了,但它给了我错误:

    grep: dir: 是目录

  2. 接下来我尝试grep在多个文件上运行。

    grep "string" .bashrc .bash_aliases完美运行。

    grep "string" .bash*也能按预期工作。

    grep "string" *给了我错误:

    grep: data: Is a directory
    grep: Desktop: Is a directory
    grep: Documents: Is a directory
    grep: Downloads: Is a directory
    ...
    

只打印了错误,没有得到匹配的行。我尝试使用该-s选项,但无济于事。

所以,我的问题是:

  1. 为什么我不能grep在目录上使用,如 (1),而我应该可以?我在互联网上看到过很多这样的例子。
    编辑:当我说“在目录中使用 grep”时,我的意思是“搜索该目录中除其子目录之外的所有文件”。我相信当您将目录而不是文件传递给 grep 时,它所做的就是这个。我错了吗?

  2. 请对我的工作原理作出解释,grep以解释(2)中命令的行为。
    编辑:让我更具体一点。为什么使用通配符指定要搜索的多个文件 可以使用.bash*而不能使用*甚至./*

  3. 如何使用搜索目录(而不是其子目录)中的所有文件grep

答案1

在 Bash 中,glob 不会扩展到隐藏文件,因此如果你想搜索全部目录中的文件,需要指定隐藏文件.*和非隐藏*

为了避免“是目录”错误,您可以使用-d skip,但在我的系统上我也收到错误grep: .gvfs: Permission denied,因此我建议使用-s,它会隐藏所有错误消息。

因此您要寻找的命令是:

grep -s "string" * .*

如果您正在另一个目录中搜索文件:

grep -s "string" /path/to/dir/{*,.*}

另一个选择是使用dotglobshell 选项,它将使 glob 包含隐藏文件。

shopt -s dotglob
grep -s "string" *

对于另一个目录中的文件:

grep -s "string" /path/to/dir/*

† 有人提到我不应该收到此错误。他们可能是对的 - 我读了一些资料,但自己却不明白其中的意思。

答案2

您需要-d skip添加该选项。

  1. Grep 在文件内部搜索。如您所说,如果您想在目录内搜索文件,则可以进行递归搜索。

  2. 默认情况下,grep 将读取所有文件并检测目录。由于默认情况下您没有使用选项定义如何处理目录-d,因此它会给出错误输出。

  3. 仅在父目录中搜索grep -d skip "string" ./*

答案3

老一辈的人可能会这么做:

find . -type f -print0 | xargs -0 grep "string"

答案4

你可以这样想,例如使用 grep。

grep -l PATH ~/.[^.]*

因此,此搜索字符串“PATH”列出用户主目录下文件的名称,仅针对以点开头的文件。

/root/.bash_history
/root/.bash_profile
grep: /root/.cache: Is a directory
grep: /root/.config: Is a directory
grep: /root/.dbus: Is a directory

使用 grep PATH ~/.[^.]* 您将看到所有出现的情况,包括带有搜索关键字的行。

/root/.bash_history:echo $PATH
/root/.bash_history:echo $PATH
/root/.bash_history:PATH=$PATH:~/bin
/root/.bash_history:echo $PATH
/root/.bash_profile:PATH=$PATH:$HOME/bin
/root/.bash_profile:export PATH
grep: /root/.cache: Is a directory
grep: /root/.config: Is a directory
grep: /root/.dbus: Is a directory

例如,为了消除错误重定向到 /dev/null

grep PATH ~/.[^.]* 2>/dev/null

/root/.bash_history:echo $PATH
/root/.bash_history:echo $PATH
/root/.bash_history:PATH=$PATH:~/bin
/root/.bash_history:echo $PATH
/root/.bash_profile:PATH=$PATH:$HOME/bin
/root/.bash_profile:export PATH

因此,您可以应用此模式在 /etc 目录中的文件中搜索“Apache”字符串 - 仅查找此主目录下的文件。您会发现这不会从 /etc/httpd/conf/httpd.conf 返回

grep Apache /etc/[^.]* 2>/dev/null
/etc/passwd:apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
/etc/services:derby-repli     4851/tcp                # Apache Derby Replication
/etc/services:derby-repli     4851/udp                # Apache Derby Replication

相关内容