打印正则表达式命中的最佳方法是什么?

时间:2014-03-20 08:48:58

标签: regex unix sed awk

我想知道仅打印regex点击的最佳,最简单的方法。

Lats说你有这个正则表达式ab[a-z][0-9]+xyz

以下数据:

cat file
her are my databc653xyzc test
some data abc12345xyzmore
what abx764xyzyes thisa sdabu9483xyzfk
not this data

然后我想得到这个结果:

abc653xyz
abc12345xyz
abx764xyz abu9483xyz


这就是我发现似乎有效的方法:

awk版本:

awk -F¤ '$0~reg {gsub(reg,"¤&¤");for (i=2;i<=NF;i+=2) printf "%s ",$i;print ""}' reg="ab[a-z][0-9]+xyz" file
abc653xyz
abc12345xyz
abx764xyz abu9483xyz

如果数据包含¤或任何用作字段分隔符的字符,则会失败。

A gnu awk(打印第二个匹配,但在单独的行上)

awk -v RS="ab[a-z][0-9]+xyz" 'RT{print RT}' file
abc653xyz
abc12345xyz
abx764xyz
abu9483xyz


sed版本(错过了第二次点击)

sed -n 's/^.*\(ab[a-z][0-9]\+xyz\).*$/\1/p' file
abc653xyz
abc12345xyz
abx764xyz

3 个答案:

答案 0 :(得分:4)

使用grep

grep -oP 'ab[a-z][0-9]+xyz' filename

它也适用于一行中的任意数量的点击。

$ cat file
her are my databc653xyzc test xyabc42xyzghi
some data abc12345xyzmore
what abx764xyzyes
not this data
$ grep -oP 'ab[a-z][0-9]+xyz' file
abc653xyz
abc42xyz
abc12345xyz
abx764xyz

如果输入中的一行中存在多个匹配,则输出中存在于同一行,您可以使用perl:

perl -lne '@m = $_ =~ /(ab[a-z][0-9]+xyz)/g; print join(" ",@m) if @m' inputfile

这会产生:

abc653xyz abc42xyz
abc12345xyz
abx764xyz

以上示例中的示例输入。

答案 1 :(得分:1)

不确定它是否是最好的,你也可以使用Perl Oneliner,因为你来自unix。

cat input.txt | perl -ne '$\ = $/; print for /(ab[a-z][0-9]+xyz)/g'

答案 2 :(得分:1)

很难根据grep对比赛进行分组。

如果 gawk 对您而言,我认为split()可以提供帮助。阅读手册页了解详细用法,例如:

kent$  cat f
abc653xyz bar abc12345xyz foo abx764xyz

kent$  awk '{c=split($0,a,"ab[a-z][0-9]+xyz",s)}c>1{for(x=1;x<=c-1;x++)printf "%s%s", s[x],(x==c-1? RS:FS)}' f
abc653xyz abc12345xyz abx764xyz