模式.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 -v
patterns.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
-P
erl 模式的一种优化,只需匹配-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
仅打印独特的线条。