GREP和RegEx - 找到模式并再次查找

时间:2012-09-29 04:13:36

标签: regex grep

这就是我想要做的事情:

在文档中搜索包含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

有办法做到这一点吗?

5 个答案:

答案 0 :(得分:6)

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

grep .*en.*en your_file

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

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

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

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

-P

有了这个,您只需将grep -P "(.*en){2}" your_file 更改为您希望它出现在一行中的多个实例,它应该可以正常工作。

编辑(查找完全相同的字两次的行)

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

en

这将打印任何一行中以grep -P "([a-z]+en).*\1" your_file 结尾的单词,该行位于该行的其他地方(en)。

值得一提的是,这与上面提到的词边界问题有关。在“bleiben”和“bleiben”的背景下,它们是平等的。但是,在“ben”和“bleiben”的上下文中,这个模式匹配,因为它会看到从“bleiben”结束“ben”作为匹配模式(从而使用“ben”= “奔”)。如果这是不可接受的,你将不得不建立一个更严格的字边界(即 - 不允许特殊字符?)。

答案 1 :(得分: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

答案 2 :(得分:1)

使用sed:

sed -rn 's/.*\b(\w+en)\b.*\b\1\b.*/\1/gp' input_file

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

使用sed

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

输出

bleiben