在匹配行之前显示文件名


281

如何grep在文件名中的匹配行之前显示文件名?


2
请告诉您的grep版本grep --version
肯特

3
肯特,grep --version这是用于了解grep版本的命令吗?如果是这样,则无法正常工作。无法找到任何其他命令来了解grep版本。
Vivek

2
好问题,但“ Os版本”是一个令人困惑的示例文件名
HaveAGuess

1
此处的操作系统和版本无关。
MD XF

grep 'pattern' *
user0

Answers:


429

试试这个小技巧,以哄骗grep它正在处理多个文件,从而显示文件名:

grep 'pattern' file /dev/null

要获取行号:

grep -n 'pattern' file /dev/null

6
是的,它有效。您能否告诉我添加/dev/null此命令的意义是什么?
Vivek

55
如果grep提供了多个文件名,它将在匹配之前自动显示文件名,但是对于单个输入文件,它将保留文件名。通过使用/dev/null作为一个额外的输入文件grep“认为”它处理多个文件,但的/ dev / null的当然是空的,所以它不会在比赛列表中显示出来..
Scrutinizer

32
使用/ dev / null是一个聪明的技巧,但是我认为-H标志下面的建议是一个更好的答案。
JohnQ

22
是的,但是-Hgrep 的选项不是POSIX的一部分,并且使用的操作系统是Solaris 10,其中标准grep或POSIX兼容版本的grep都不具有该-H选项。
审查者

4
如果您将grep与find一起使用,那很重要,例如find . -name foo -exec grep pattern {} \;-假设foo您的子目录中有很多文件已命名,find但仍grep一次处理一个文件。这个/dev/null技巧似乎可以在我尝试过的所有linux / osx风格中起作用,所以赞!请注意,我认为这样做-H比较干净,但是如下所述,您的版本可能不支持它grep
乔恩五世

295

如果您有选择-H并且-n可以使用(man grep是您的朋友):

$ cat file
foo
bar
foobar

$ grep -H foo file
file:foo
file:foobar

$ grep -Hn foo file
file:1:foo
file:3:foobar

选项:

-H,--with-filename

打印每个匹配项的文件名。当要搜索多个文件时,这是默认设置。

-n,--line-number

在输出的每一行之前,在其输入文件中添加从1开始的行号。(-n由POSIX指定。)

-H是GNU扩展,但-n由POSIX指定


3
不,-H这里不支持。
Vivek

1
支持,但始终提供grep:文件:
无此

2
在ubuntu -H和-n上工作。可能带有* nix的所有较新版本
tgkprog 2014年

1
多年来,我一直在为此苦苦挣扎,甚至没有想到这些选择!
2015年

45

没有必要的技巧。

grep --with-filename 'pattern' file

带行号:

grep -n --with-filename 'pattern' file

3
@codeforester我不知道其他任何人grep,所以我也不知道。
MD XF

2
好酷!这适用于linux。如果您使用的是Mac,则可以在brew中安装coreutils。并记住将PATH =“ / usr / local / opt / coreutils / libexec / gnubin:$ PATH”添加到您的文件中
。.bashrc

2
这(也)在MinGW(我认为是1.0.17)中有效。
彼得·莫滕森

它适用于我的内置Mac grep(2.5.1-FreeBSD)。但是要使用Homebrew的替代grep,另一种方法是先运行brew install grep然后使用ggrep。无需修改PATH。
wonderlr

5

怎么样,我设法实现了这一点,部分归功于这篇文章。

您想在带有模式(例如filename=logfile.DATE)的几个目录中找到多个文件,比方说具有不同名称但模式(例如)的日志/logsapp1, /logsapp2。每个文件都有一个您想grep的模式(例如"init time"),并且您想拥有"init time"每个文件的模式,但要知道它属于哪个文件。

find ./logsapp* -name logfile* | xargs -I{} grep "init time" {} \dev\null | tee outputfilename.txt

然后outputfilename.txt会像

./logsapp1/logfile.22102015: init time: 10ms
./logsapp1/logfile.21102015: init time: 15ms
./logsapp2/logfile.21102015: init time: 17ms
./logsapp2/logfile.22102015: init time: 11ms

一般来说

find ./path_pattern/to_files* -name filename_pattern* | xargs -I{} grep "grep_pattern" {} \dev\null | tee outfilename.txt

说明:

find 命令将根据模式搜索文件名

然后,管道xargs -I{}会将find输出重定向到{}

这将是输入 grep ""pattern" {}

然后grep显示文件名的技巧\dev\null

最后,将输出写入文件 tee outputfile.txt

这在grep1989年的9.0.5版中对我有用。


3
或仅使用查找find ./path_pattern/to_files -type f -name "files*.log" -exec grep -Hn pattern {} \;
马丁

1

这是对先前解决方案的略微修改。我的示例在bash脚本中查找stderr重定向: grep '2>' $(find . -name "*.bash")


-7
grep 'search this' *.txt

为我工作,以搜索所有.txt文件(当然,请输入您自己的搜索值)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.