在 Cygwin 上使用 grep 提取匹配的单词

在 Cygwin 上使用 grep 提取匹配的单词

我正在使用 Cygwin,所以我一直在查看 POSIX 正则表达式信息。

我正在尝试在 xml 文件中搜索字符串,并且不断获取整行,但似乎无法将结果缩小到我要查找的几个字符。

文件 (file1) 有许多实例:

<!ENTITY abc123456 SYSTEM "../blah/abc123456.xyz" NDATA xyz>
<!ENTITY abc123457 SYSTEM "../blah/abc123457.xyz" NDATA xyz>
<!ENTITY abc123458 SYSTEM "../blah/abc123458.xyz" NDATA xyz>

grep 结果列出了整行,但我试图将结果缩小到:

abc123456.xyz
abc123457.xyz
abc123458.xyz

以下成功地给了我这些行:

grep -E abc[[:digit:]] file1
grep abc[0-9] file1
grep "abc[[:digit:]]" file1

由于我要查找的内容不在行的开头或结尾,因此 ^ 和 $ 似乎没有用。不知道如何锚定我正在搜索的内容。我尝试了很多其他使用 grep 的变体,但都没有成功。

答案1

一定有更优雅的解决方案(也许grep -P是一个?),但是在简单的方法不够的情况下,您可以使用sed它来模拟grep并获取您想要的字符串:grep -o

sed -nr 's/.*SYSTEM "..\/blah\/([^"]*).*/\1/p'

这基本上会匹配整个字符串,然后将其完全替换为您要查找的子字符串。

答案2

grep 命令打印包含匹配项的行。无论您使用什么模式来匹配该行的一部分,grep 都会打印整行。

GNU grep 是 Cygwin 中包含的版本,它可以选择仅显示与模式匹配的行部分:-o

grep -o 'abc[0-9][^"]*' file1

您可以\b在模式的开头添加以仅匹配空格或标点符号之后,即避免匹配/fooabc123.xyz。如果您想在/or后专门匹配",标点符号将包含在输出中;你可以用a来避免这种情况后向断言它在 Perl 正则表达式语法中可用。

grep -o -P '(?<=[/"])abc[0-9][^"]*' file1

相关内容