5

这是我想要做的:

在文档中搜索包含 RegEx 的模式,然后检查该确切模式是否在一行内出现两次。

Content of file.xml:
(some code) "testen"  (more code)  >testete<
(some code) "bleiben" (more code)  >bleiben<
(some code) "stehen"  (more code)  >stand<
(some code) "hängen"  (more code)  >hängten<
... 

现在我想检查.*en并检查(确切)相同的单词是否在该行中出现两次。所以结果应该是:

bleiben

因为 Testen != testete, stehen != stand, hängen != hängten

有没有办法做到这一点?

4

5 回答 5

7

grep您可以使用以下模式在第一行处理此搜索.*en.*en::

grep .*en.*en your_file

这将仅输出en在其中出现两次的行。

如果您需要在两个 back-to-back 中处理它grep,您仍然可以在管道版本中使用相同的命令:

grep .*en your_file | grep .*en.*en

此外,如果您想增加同一行中的实例数,您可以利用grep'-P选项并使用 Perl 正则表达式:

grep -P "(.*en){2}" your_file

有了这个,您可以将它更改为{2}您希望它出现在一行中的任意多个实例,它应该可以工作。

编辑(查找具有完全相同单词的行两次)

如果没有可以定义单词边界的扩展模式,这很困难 - 而且您的示例输出并没有太大帮助。举一个直截了当的例子,我们可以假设“单词”是任何以 .a-z结尾的字母字符串en。您可以根据需要自定义此边界:

grep -P "([a-z]+en).*\1" your_file

这将打印任何以在该行其他地方找到的单词结尾en的行 (the \1)。

需要提一下的一个警告,它与上面提到的词边界问题有关。在“bleiben”和“bleiben”的上下文中,它们是平等的。但是,在 "ben" 和 "bleiben" 的上下文中,此模式也会匹配,因为它会将 "bleiben" 的结尾 "ben" 视为匹配模式(因此使用 "ben" = "ben")。如果这是不可接受的,您将不得不建立一个更严格的字边界(即 - 不允许特殊字符?)。

于 2012-09-29T04:24:54.733 回答
1

这是使用GNU awk. 我假设两次你的意思是两次或更多次。像这样运行:

awk -f script.awk file.xml

内容script.awk

/.*en/ { 
    gsub(/["<>]/, " ")
    for (i=1; i<=NF; i++) {
        if ($i ~ /.*en/) {
            array[$i]++
        } 
    }
}
{
    for (j in array) {
        if (array[j]>=2) {
            print j
        }
    }
    delete array
}

或者,这是单线:

awk '/.*en/ { gsub(/["<>]/, " "); for (i=1; i<=NF; i++) if ($i ~ /.*en/) array[$i]++ } { for (j in array) if (array[j]>=2) print j; delete array }' file.xml
于 2012-09-29T04:58:11.673 回答
1

使用 sed:

sed -rn 's/.*\b(\w+en)\b.*\b\1\b.*/\1/gp' input_file
于 2012-09-29T05:07:19.643 回答
0

您可以使用 grep 的-o选项仅返回该行的匹配部分

这是一个链接,表明 awk 可能是完成这项工作的更好工具:

于 2012-09-29T04:35:16.457 回答
0

使用 sed

sed -n  's/[^"]\+"\([^"]\+\)"[^>]\+>\1</\1/p' FileName.txt

输出 :

bleiben
于 2012-09-29T10:31:08.953 回答