Regex sed/grep/awk?:将匹配模式追加到行尾

Regex sed/grep/awk?:将匹配模式追加到行尾,regex,awk,sed,grep,Regex,Awk,Sed,Grep,我有一个文件,比如 1,ab012a800,20141205 2,ab023a801,20141205 3,ab012a802,20141205 1,ab024a803,20141205 1,ab012a804,20141205 我想提取'ab012a'部分并将其附加到行的末尾 1,ab012a800,20141205,ab012a 2,ab023a801,20141205,ab023a 3,ab012a802,20141205,ab012a 1,ab024a803,20141205,ab02

我有一个文件,比如

1,ab012a800,20141205
2,ab023a801,20141205
3,ab012a802,20141205
1,ab024a803,20141205
1,ab012a804,20141205
我想提取'ab012a'部分并将其附加到行的末尾

1,ab012a800,20141205,ab012a
2,ab023a801,20141205,ab023a
3,ab012a802,20141205,ab012a
1,ab024a803,20141205,ab024a
1,ab012a804,20141205,ab012a
1,ab012a800,20141205,ab012a
2,ab023a801,20141205,ab023a
3,ab012a802,20141205,ab012a
1,ab024a803,20141205,ab024a
1,ab012a804,20141205,ab012a
我可以用grep提取:

grep -o '^[a-z][a-z][0-9]*[a-z]' file    
并将以下内容附加到带有sed的行:

sed "s/$/,whatever/"
sed '/^[a-z][a-z][0-9]*[a-z]/ s/$/something/' file
甚至用sed替换模式:

sed "s/$/,whatever/"
sed '/^[a-z][a-z][0-9]*[a-z]/ s/$/something/' file
但是我如何将匹配的模式附加到行的末尾呢

非常感谢捕获组:

$ sed -r 's@^([0-9]+,)(ab[0-9]+[a-z]+)(.*)@\1\2\3,\2@g' file
1,ab012a800,20141205,ab012a
2,ab023a801,20141205,ab023a
3,ab012a802,20141205,ab012a
1,ab024a803,20141205,ab024a
1,ab012a804,20141205,ab012a
您可以使用:

sed -i.bak 's/\(,[a-z][a-z][0-9]*[a-z]\).*$/&\1/' file
1,ab012a800,20141205,ab012a
2,ab023a801,20141205,ab023a
3,ab012a802,20141205,ab012a
1,ab024a803,20141205,ab024a
1,ab012a804,20141205,ab012a
&
是一个特殊的替换符号,表示所使用的正则表达式完全匹配的字符串,
\1
表示匹配的组1。

awk 'match($0,/[a-z][a-z][0-9]+[a-z]/,a){print $0","a[0]}' file
匹配字符串,然后打印行和匹配的字符串

替代便携式awk方式(埃德默顿提供)

并带有字符类以实现最大的可移植性

awk 'match($0,/[[:lower:]][[:lower:]][[:digit:]]+[[:lower:]]/{
     $0=$0","substr($0,RSTART,RLENGTH)}1' file

在没有任何其他约束的情况下,基于此示例…

您可以使用此
GNU awk

awk -F"," '{print $1","$2","$3"," gensub(/(.*)(...$)/, "\\1", "g", $2)}' FileName
输出:


我的输出是:
,AB012AA80020141205,AB023AA80120141205,AB012AA80220141205,AB024AA80320141205,AB012AA80420141205
输入的每一行都有尾随空格吗?@anubhava就是这样。现在工作。谢谢,不用谢,很高兴成功了@Jidder:看看inout数据,我们真的不需要匹配那个数字。这需要
gnu awk
,因为
gensub
,这将是gnu awk,因为第三个参数是match(),此时IMHO gensub()更直观。可移植的awk方式是
match($0,/[a-z][a-z][0-9]+[a-z]/{$0=$0”,“substr($0,RSTART,RLENGTH)}1'文件
(尽管使用字符类)。@EdMorton我个人认为match更容易阅读,但它是依赖于GAWK的。我现在将添加你的可移植的。你说使用字符类是什么意思?我的意思是使用
[:lower:]
而不是
[a-z]
例如,因为在某些语言环境中,一些大写字母包含在范围
a-z
中,例如,某些语言环境的字符顺序为
aAbBcC…zZ
而不是
abc…zABC…z
,因此在这些语言环境中
a-z
表示除
z
以外的所有小写字母和大写字母,而不是所有小写字母仅限e字母。这就是字符类存在的原因-例如,
[[:lower:]
始终表示所有小写字母,而不考虑语言环境。idk可以确定
[0-9]
[:digit:]
之间是否存在歧义。
perl -pe 's/(.{7})(.*)/$1$2,$1/' file
awk '{print $1"," substr($0,3,6)}' file

1,ab012a800,20141205,ab012a
2,ab023a801,20141205,ab023a
3,ab012a802,20141205,ab012a
1,ab024a803,20141205,ab024a
1,ab012a804,20141205,ab012a