使用 grep 和文件中的模式打印不匹配的模式

使用 grep 和文件中的模式打印不匹配的模式

模式.txt:

"BananaOpinion"
"ExitWarning"
"SomeMessage"
"Help"
"Introduction"
"MessageToUser"

字符串.xml

<string name="Introduction">One day there was an apple that went to the market.</string>
<string name="BananaOpinion">Bananas are great!</string>
<string name="MessageToUser">We would like to give you apples, bananas and tomatoes.</string>

预期输出:

"ExitWarning"
"SomeMessage"
"Help" 

如何打印 中 中patterns.txt未找到的术语Strings.xml?我可以打印匹配/不匹配的线Strings.xml,但如何打印不匹配的图案?我正在使用 ggrep (GNU grep) 版本 2.21,但我对其他工具持开放态度。如果这与我找不到的另一个问题重复,我们深表歉意。

答案1

您可以仅打印匹配的部分,并将结果用作原始文件grep -o的模式:grep -vpatterns.txt

grep -oFf patterns.txt Strings.xml | grep -vFf - patterns.txt

尽管在这种特殊情况下您也可以使用join+ sort

join -t\" -v1 -j2 -o 1.1 1.2 1.3 <(sort -t\" -k2 patterns.txt) <(sort -t\" -k2 strings.xml)

答案2

最好的方法可能是 @don_crissti 建议的,所以这是同一主题的变体:

$ grep -vf <(grep -Po 'name=\K.+?"' Strings.xml) patterns.txt
"ExitWarning"
"SomeMessage"
"Help"

这基本上与@don_crissti 的方法相反。它使用 grep 与 Perl 兼容正则表达式 ( -P) 和-o开关来仅打印该行的匹配部分。然后,正则表达式查找name=并丢弃它 ( \K),然后查找一个或多个字符,直到第一个"( .+?")。这会产生文件中存在的模式列表String.txt,然后使用该列表将其作为输入传递给反向 grep ( grep -v)流程替代( <(command))。

答案3

我可能会用cut。也就是说,如果您知道在哪里可以找到您要查找的带引号的字符串。

如果我做:

{   cut  -sd\" -f2 |
    grep -vFf- pat
}   <<\IN
#   <string name="Introduction">One day there was an apple that went to the market.</string>
#   <string name="BananaOpinion">Bananas are great!</string>
#   <string name="MessageToUser">We would like to give you apples, bananas and tomatoes.</string>
IN

...保存我自己的示例副本并运行上述命令后,patterns.txt输出pat为:

"ExitWarning"
"SomeMessage"
"Help"

cut仅将每个分隔符匹配的输入行的第二个"双引号-d限定字段打印到标准输出,并取消所有其他字段。-f-s

cut实际打印的内容grep是:

Introduction
BananaOpinion
MessageToUser

grep在其命名文件操作数中搜索与其stdin 模式文件中的固定字符串-v不匹配的行。-F--f

如果您可以依赖第二个"-delimited 字段作为匹配字段,那么它肯定是对grep -Perl 模式的一种优化,只需匹配-F固定字符串和其中的一小部分,因为cut繁重的工作确实如此 - 并且它做到了快速地

答案4

另一种方法是将 Patterns.txt 和 Strings.xml 放入一个列表中并查找唯一的行

cat patterns.txt Strings.xml | grep -oFf patterns.txt | sort | uniq -u

解释:

cat patterns.txt Strings.xml将所有内容放入一个列表中。 grep -oFf patterns.txt删除每行上的垃圾。 sort不言自明的。对所有行进行排序。 uniq -u仅打印独特的线条。

相关内容