我有一个包含这样的行的文件:
"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(后向引用)匹配。但是,输出为零。 我怎么能这样做?
答案 0 :(得分:2)
我发现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。
答案 1 :(得分:1)
使用sed
sed -n '/\({[^{]*}\).*\1/p' file
"def{word} def{word}"
如果只导出单词
sed -n 's/.*{\([^{]*\)}.*{\1}.*/\1/p' file
word
答案 2 :(得分:0)
#!/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中,你可以更容易地扩展和维护。
答案 3 :(得分:0)
是的,有很多方法可以做到这一点,包括:
perl -lne '/def\{(.+?)\}.*def\{\1\}/ and print $1' filename