bash regexp 以查找具有重复单词的行



我有一个文件,里面有这样的行:

"def{word}  def{word}"
"def{worad} def{worads}"

我想报告出现两次的大括号单词。所以在这种情况下,输出应该只是"单词"我拥有的是:

#!/bin/bash
arr=(
   "def{word}  def{word}"
   "def{worad} def{worads}"
)
for i in "${arr[@]}"; do 
   [[ $i =~ def{([a-z]+)}.*def{1} ]] || continue
   echo ${BASH_REMATCH[1]}
done

即,我尝试将第一个单词与\1(反向引用)匹配。但是,输出为零。我该怎么做?

我发现 bash 正则表达式在括在引号中时表现得更好,即使你必须对此有点小心,因为直接引用会导致精确匹配而不是正则表达式匹配。 要解决此问题,您可以将正则表达式放在变量中,引号,然后在=~表达式中引用它:

#!/bin/bash
arr=(
   "def{word}  def{word}"
   "def{worad} def{worads}"
)
re="def{([a-z]+)}.*def{1}"
for i in "${arr[@]}"; do 
   [[ $i =~ $re ]] || continue
   echo ${BASH_REMATCH[1]}
done

输出:

$ ./worad.sh 
word
$ 

不过,这似乎只适用于 Bash v4。

使用 sed

sed -n '/({[^{]*}).*1/p' file
"def{word}  def{word}"

如果只导出单词

sed  -n 's/.*{([^{]*)}.*{1}.*/1/p' file
word

for bash中的循环真的很慢,这对于bash来说可能有点复杂。 我会为此推荐python或awk。 这里有一些 python 代码可以做你想做的事情:

#!/usr/bin/env python
import re
import sys 
import itertools
def freq(alist):
    counts = {}
    for x in alist:
        x = x[1:-1]
        counts[x] = counts.get(x,0) + 1 
    return {m:[j[0] for j in n] for m,n in itertools.groupby(counts.iteritems(), lambda y: y[1])}
for line in sys.stdin:
    counts = freq(re.findall(r'{[^}]*}', line))
    if 2 in counts:
        print ' '.join(counts[2])
    else:
        print

假设此脚本位于名为 two.py 文件中,如下所示运行:

cat yourfile | python two.py

现在它在python中,你有一些更容易扩展和维护的东西。

是的,有很多方法可以做到这一点,包括:

perl -lne '/def{(.+?)}.*def{1}/ and print $1' filename

相关内容

  • 没有找到相关文章

最新更新