文件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