协慌网

登录 贡献 社区

grep 可以仅显示与搜索模式匹配的单词吗?

有没有一种方法可以从与搜索表达式匹配的文件中使 grep 输出 “单词”?

如果我想在多个文件中找到 “th” 的所有实例,则可以执行以下操作:

grep "th" *

但是输出将是这样的(我大胆);

some-text-file : the cat sat on the mat  
some-other-text-file : the quick brown fox  
yet-another-text-file : i hope this explains it thoroughly

使用相同的搜索,我希望它输出的是:

the
the
the
this
thoroughly

使用 grep 可以吗?还是使用其他工具组合?

答案

试试 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.

交叉分发安全答案(包括 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 语法(请参阅下文)

grep 手册中的更多内容

-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:]]而不是其等同于\w perl。 有关更多信息,请参见 Wikipedia 页面。

最终,无论 grep 使用哪种平台(原始版本),上述 POSIX 答案都将更加可靠

对于不带 - o 选项的 grep 支持,第一个 grep 输出相关行,tr 将空格拆分为新行,最后的 grep 过滤器仅针对各个行。

(PS:我知道到目前为止,大多数平台都已经针对 \ w .... 进行了修补,但是总是有些落后)

感谢 @AdamRosenfield 答案中的 “-o” 解决方法

这比您想像的要简单。试试这个:

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.