我有一个看起来像这样的文件:
254529 ANN=C|blabla,T|blabla,A|blabla
254540 ANN=T|blabla,G|blabla,C|blabla
254586 ANN=TTGG|blabla,A|blabla
我想用逗号替换文件中的逗号,然后在行首添加数字。
我文件中的 blabla
实际上是很长的文字,出于可读性考虑,我在此处进行了更改。每个blabla
都不同。
我尝试了以下操作,但它仅替换了该行中的最后一个逗号。
sed -e 's/^\(.*\)\(\t.*\),/\1\2,\1\t/g' file
这是我得到的:
254529 ANN=C|blabla,T|blabla,254529 A|blabla
254540 ANN=T|blabla,G|blabla,254540 C|blabla
254586 ANN=TTGG|blabla,254586 A|blabla
虽然我想获得这个:
254529 ANN=C|blabla,254529 T|blabla,254529 A|blabla
254540 ANN=T|blabla,254540 G|blabla,254540 C|blabla
254586 ANN=TTGG|blabla,254586 A|blabla
使用sed可以做到吗?
谢谢
答案 0 :(得分:0)
问题在于,g
不会进行全局替换。简单的解决方案是重复替换次数,只要有逗号即可。像这样:
$ sed ':a; s/^\(.*\)\(\t.*\),/\1\2\n\1\t/; ta; s/\n/,/g' file
254529 ANN=C|blabla,254529 T|blabla,254529 A|blabla
254540 ANN=T|blabla,254540 G|blabla,254540 C|blabla
254586 ANN=TTGG|blabla,254586 A|blabla
工作原理:
:a
这将创建标签a
。
s/^\(.*\)\(\t.*\),/\1\2\n\1\t/
这将执行您的替换(稍作修改)。由于.*
是“贪婪的”,因此它将在该行的最后一个逗号处执行它。
由于.*
是“贪婪的”,因此是否应用g
修饰符并不重要:只会匹配最后一个逗号,并且只会执行一个替换。
与您的命令的不同之处在于,在输出中,逗号用换行符代替。这样一来,我们就不会尝试在同一逗号上再次重复替换。
ta
如果最后一次替换成功,则跳回到标签a。
s/\n/,/g
将所有换行符转换回逗号。
$ awk -F'\t' '{gsub(/,/, ","$1"\t")} 1' file
254529 ANN=C|blabla,254529 T|blabla,254529 A|blabla
254540 ANN=T|blabla,254540 G|blabla,254540 C|blabla
254586 ANN=TTGG|blabla,254586 A|blabla