有没有办法使grep输出与搜索表达式匹配的文件中的“单词”?
如果我想在许多文件中找到“ th”的所有实例,则可以执行以下操作:
grep "th" *
但是输出将是这样的(我大胆);
一些文本文件:在猫坐在了垫子 一些-其他文本文件:在敏捷的棕色狐狸 另一个文本文件:我希望这能彻底解释它
使用相同的搜索,我希望它输出的是:
the
the
the
this
thoroughly
使用grep可以吗?还是使用其他工具组合?
有没有办法使grep输出与搜索表达式匹配的文件中的“单词”?
如果我想在许多文件中找到“ th”的所有实例,则可以执行以下操作:
grep "th" *
但是输出将是这样的(我大胆);
一些文本文件:在猫坐在了垫子 一些-其他文本文件:在敏捷的棕色狐狸 另一个文本文件:我希望这能彻底解释它
使用相同的搜索,我希望它输出的是:
the
the
the
this
thoroughly
使用grep可以吗?还是使用其他工具组合?
Answers:
试试grep -o
grep -oh "\w*th\w*" *
编辑:从菲尔的评论匹配
从文档:
-h, --no-filename
Suppress the prefixing of file names on output. This is the default
when there is only one file (or only standard input) to search.
-o, --only-matching
Print only the matched (non-empty) parts of a matching line,
with each such part on a separate output line.
"\w*th\w*" *
意思,所以我认为应该发表。\w
是[_ [:alnum:]],因此它基本上匹配任何包含'th'的“单词”(因为\w
不包含空格)。引用部分后面的*是该文件的全局名称(即,匹配该目录中的所有文件)
\w
通常不便于携带grep -E
; 为了获得适当的可移植性,请改用POSIX字符类名称[[:alnum:]]
(或者[_[:alnum:]]
如果您也确实需要下划线;或者尝试grep -P
在平台上使用下划线)。
-h
我完全有必要说..?
交叉分发安全答案(包括Windows minGW?)
grep -h "[[:alpha:]]*th[[:alpha:]]*" 'filename' | tr ' ' '\n' | grep -h "[[:alpha:]]*th[[:alpha:]]*"
如果您使用的旧版grep(例如2.4.2)不包含-o选项。使用上面的。否则,使用下面更简单的维护版本。
Linux交叉分发安全答案
grep -oh "[[:alpha:]]*th[[:alpha:]]*" 'filename'
要汇总-oh
输出正则表达式匹配到文件内容(而不是文件名)的方法,就像您希望正则表达式在vim / etc中工作一样...然后您要搜索的单词或正则表达式取决于您!只要您继续使用POSIX而不是perl语法(请参阅下文)
-o Print each match, but only the match, not the entire line.
-h Never print filename headers (i.e. filenames) with output lines.
-w The expression is searched for as a word (as if surrounded by
`[[:<:]]' and `[[:>:]]';
原始答案不适用于所有人的原因
\w
平台的用法因平台的“ perl”扩展语法而异。因此,仅限用于POSIX字符类的grep安装使用[[:alpha:]]
,而不使用其perl等效项\w
。有关更多信息,请参见Wikipedia页面。
最终,无论grep的平台(是原始版本)如何,上述POSIX答案都将更加可靠
对于不带-o选项的grep支持,第一个grep输出相关行,tr将空格拆分为新行,最后的grep过滤器仅针对各个行。
(PS:我知道到目前为止,大多数平台都已经为\ w ....进行了修补,但是总是有些滞后)
感谢@AdamRosenfield答案中的“ -o”解决方法
-o
选项在git软件包(minGW?)安装的Windows grep中不存在: "c:\Program Files (x86)\Git\bin\grep" --version grep (GNU grep) 2.4.2
这比您想像的要简单。尝试这个:
egrep -wo 'th.[a-z]*' filename.txt #### (Case Sensitive)
egrep -iwo 'th.[a-z]*' filename.txt ### (Case Insensitive)
哪里,
egrep: Grep will work with extended regular expression.
w : Matches only word/words instead of substring.
o : Display only matched pattern instead of whole line.
i : If u want to ignore case sensitivity.
您可以将空格转换为换行符,然后进行grep转换,例如:
cat * | tr ' ' '\n' | grep th
tr
,那么他可以grep
首先执行,因此tr
仅适用于匹配的行:grep th filename | tr ' ' '\n' | grep th
只是awk
,不需要工具的组合。
# awk '{for(i=1;i<=NF;i++){if($i~/^th/){print $i}}}' file
the
the
the
this
thoroughly
我对awk难以记住的语法不满意,但是我喜欢使用一个实用程序来执行此操作的想法。
似乎ack(如果使用Ubuntu,则为ack-grep)可以轻松做到这一点:
# ack-grep -ho "\bth.*?\b" *
the
the
the
this
thoroughly
如果省略-h标志,则会得到:
# ack-grep -o "\bth.*?\b" *
some-other-text-file
1:the
some-text-file
1:the
the
yet-another-text-file
1:this
thoroughly
另外,您可以使用--output
标志使用我发现的最简单的语法来执行更复杂的搜索:
# echo "bug: 1, id: 5, time: 12/27/2010" > test-file
# ack-grep -ho "bug: (\d*), id: (\d*), time: (.*)" --output '$1, $2, $3' test-file
1, 5, 12/27/2010
您可以将grep输出通过管道传输到Perl中,如下所示:
grep "th" * | perl -n -e'while(/(\w*th\w*)/g) {print "$1\n"}'