使用 grep 搜索以非单词字符开头的单词

使用 grep 搜索以非单词字符开头的单词

文件testing.txt的内容是:

ls -a
cmake --verbose
verbose

我想用来grep查看这个文件并只找到以“--”开头的单词,即单词“--verbose”

然而,使用以下模式作为参数是grep行不通的:

$ cat testing.txt | grep -- 
Usage: grep [OPTION]... PATTERN
   [FILE]... Try 'grep --help' for more information.

$ cat testing.txt | grep -
ls -a
cmake --verbose

$ cat testing.txt | grep '--v'
grep (GNU grep) 3.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Haertel and others, see <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.

$ cat testing.txt | grep ver
cmake --verbose
verbose

$ cat testing.txt | grep '-ver'
ls -a
  • grep认为所有以 a 开头的参数--都是选项?如何防止这种情况发生,以便 grep 可以搜索以“--”开头的模式(在文件中)?
  • 最后一次尝试使用模式“-ver”,因此grep不认为该模式是一个选项,但随后grep与文件中的单词“--verbose”不匹配,即使它包含模式“-ver”。是什么导致了这种行为?

答案1

当该字符串--出现在命令行上时,对于大多数实用程序来说都是特殊的。它发出信号选项结束到命令行参数解析器。它用于您可能想要传递以破折号开头的文件名的情况,例如rm -- -f(删除-f当前目录中调用的文件)。

要用作--的模式grep,请明确告诉实用程序它是一个模式:

grep -e --

选项-e接受一个选项参数,它是您要搜索grep的模式。grep

你也可以使用

grep -- --

这里,grep知道第二个--是模式,因为第一个--说它不能是一个选项。


您的最后一个管道会返回,ls -a因为该文件中的一行不包含r.该命令grep -ver也可以写成grep -v -e r“提取所有与( -v)不匹配r( -e r)的行”。

答案2

要回答标题中的问题(我将其解释为含义:报告不以字母数字或下划线开头的空格分隔的单词(\w在某些正则表达式引擎中),您可以使用 GNU 来完成,grep前提是它是使用 PCRE 支持构建的:

grep -Po '(?<!\S)[^\w\s]\S*'

^这是除单词一 ( \w) 或空白一 ( ) 以外的字符 ( ),\s前提是其前面 ( (?<!...)) 没有非空白 ( \S),并且后面没有任意数量 ( *) 的非空白 ( \S)。

您的输入会返回:

-a
--verbose

答案3

您可以GNU grep通过positive lookarounds如下方式解决此问题:

 $ grep -oP '(?:(?!\h)\W)+\w+' inp

读起来,从我在字符串中的位置来看,我看到一个单词后面有一个非单词。但是,这个非单词排除了任何空格。

输出:

 -a
 --verbose

相关内容