我想在目录中的所有文件中搜索一串文本(而不是它的子目录;我知道该-r
选项可以做到这一点,但这不是我想要的)。
跑步
grep "string" /path/to/dir
应该可以做到这一点,我已经读过了,但它给了我错误:
grep: dir: 是目录
接下来我尝试
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
选项,但无济于事。
所以,我的问题是:
为什么我不能
grep
在目录上使用,如 (1),而我应该可以?我在互联网上看到过很多这样的例子。
编辑:当我说“在目录中使用 grep”时,我的意思是“搜索该目录中除其子目录之外的所有文件”。我相信当您将目录而不是文件传递给 grep 时,它所做的就是这个。我错了吗?请对我的工作原理作出解释,
grep
以解释(2)中命令的行为。
编辑:让我更具体一点。为什么使用通配符指定要搜索的多个文件 可以使用.bash*
而不能使用*
甚至./*
?如何使用搜索目录(而不是其子目录)中的所有文件
grep
?
答案1
在 Bash 中,glob 不会扩展到隐藏文件,因此如果你想搜索全部目录中的文件,需要指定隐藏文件.*
和非隐藏*
。
为了避免“是目录”错误,您可以使用-d skip
,但在我的系统上我也收到错误grep: .gvfs: Permission denied
†,因此我建议使用-s
,它会隐藏所有错误消息。
因此您要寻找的命令是:
grep -s "string" * .*
如果您正在另一个目录中搜索文件:
grep -s "string" /path/to/dir/{*,.*}
另一个选择是使用dotglob
shell 选项,它将使 glob 包含隐藏文件。
shopt -s dotglob
grep -s "string" *
对于另一个目录中的文件:
grep -s "string" /path/to/dir/*
† 有人提到我不应该收到此错误。他们可能是对的 - 我读了一些资料,但自己却不明白其中的意思。
答案2
您需要-d skip
添加该选项。
Grep 在文件内部搜索。如您所说,如果您想在目录内搜索文件,则可以进行递归搜索。
默认情况下,grep 将读取所有文件并检测目录。由于默认情况下您没有使用选项定义如何处理目录
-d
,因此它会给出错误输出。仅在父目录中搜索
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