sed - 如何使用 sed 将匹配模式替换为行首?
问题描述
我有一个看起来像这样的文件:
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 吗?
谢谢
解决方案
使用 sed
问题是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
$ 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
推荐阅读
- scala - 如何解码嵌套在circe数组中的日期?
- sql - 错误:重复键值违反唯一约束
- java - 文件路径正确时的 java.lang.ClassNotFoundException
- python - 如何将某些东西添加到属性中?
- sftp - 编辑文件时 SFTP 上的 WinSCP 更改所有者
- regex - 通过另一列编辑 CSV 列
- variables - 我无法弄清楚不可编译的源代码 - 变量可能尚未初始化
- python - 使用 Python 加快查找和替换代码的速度?
- c++ - 调用析构函数后 C++ 动态模板队列“双重释放或损坏(出)”
- node.js - 如何让 HTTPS 在 Windows 10 的命令行中工作(请注意 HTTP 正在工作)?