如何用逗号替换特定模式后的空格?

时间:2019-01-23 23:39:57

标签: regex shell sed bioinformatics

我是编码的新手,我正在尝试格式化一些生物信息学数据。我试图用逗号删除GT:GL:GOF:GQ:NR:NV之后的所有空格,但不要删除格式xx:xx:xx:xx:xx以外的任何空格(如示例)。我知道我需要将sed与regex选项一起使用,但是我对如何使用它并不十分熟悉。我以前从未真正使用过sed,并且对尝试感到困惑,因此不胜感激。抱歉,如果我格式化不当(这是我的第一篇文章)。

编辑2:这次我从文件中获取了实际数据,这可能有助于解决问题。删除了不良示例。

新示例:我从实际文件中提取了此数据(这只是两个样本),并且被其他数据包围。本质上,该行包含一堆数据,后跟“ GT:GL:GOF:GQ:NR:NV”,此后,下面所示的格式有更多的数据,最后还有更多的随机数据。不幸的是,我无法发布完整的数据行,因为它非常长且无法容纳。

输入

0/1:-1,-1,-1:146:28:14,14:4,0 0/1:-1,-1,-1:134:6:2,2:1,0

输出

0/1:-1,-1,-1:146:28:14,14:4,0,0/1:-1,-1,-1:134:6:2,2:1,0

5 个答案:

答案 0 :(得分:2)

我假设... npm run xcopyKeys4Winxx:xx:xx可以有任意数量的部分,因为有些部分有3个,有些部分有4个。

要使用xx:xx:xx:xx可靠地做到这一点非常困难,因为它不支持环视,在本示例中似乎需要使用环视。

您可以尝试以下操作:

sed

如果您对perl -pe 's/(?<=\d) (?=\d+(:\d+){2,})/,/g' input.txt 充满信心,可以尝试一下,但是可能会遗漏某些情况:

sed

答案 1 :(得分:2)

使用基本正则表达式,您可以使用字符类反向引用来完成任务,例如

$ sed 's/\([0-9][0-9]*:[0-9][0-9]*\)[ ]\([0-9][0-9]*:[0-9][0-9]*\)/\1,\2/g' file
1/0 ./. 0/1 GT:GL:GOF:GQ:NR:NV 1:12:314,213:132:13:31,14:31:31 AB GT BB
1/0 ./. 0/1 GT:GL:GOF:GQ:NR:NV 10:13:12,41:41:1:13,13:131:1:1 AB GT RT
1/0 ./. 0/1 GT:GL:GOF:GQ:NR:NV 1:12:314,213:132:13:31,14:31:31 AB GT

基本上说:

  • 找到并捕获任何[0-9][0-9]*个或多个数字,
  • :
  • 分隔
  • 后接[0-9][0-9]*一个或多个数字-作为捕获组1,
  • 匹配捕获组1之后是捕获组2的空间(与捕获组1相同),
  • 然后最后用逗号替换捕获组之间的空格,并使用反向引用1和2(例如\1\2)重新插入捕获组文本,最后
  • 进行替换 global (例如g)以替换所有匹配项。

基于发布的新输入进行编辑

如果您仍然需要添加所有原始逗号,请现在要在,0 0/之间添加逗号(其中逗号在单位数字前加一个空格要用逗号替换,后跟一个数字和一个正斜杠),那么您需要做的就是使捕获组成为有条件的(如上所述捕获原始数据,或者捕获这个新段。)为此,请在条件之间包含一个OR(例如,基本正则表达式中的\|)。

例如,在第一个捕获组的末尾添加\|,[0-9],在第二个捕获组的末尾添加\|[0-9][/],例如

$ sed 's/\([0-9][0-9]*:[0-9][0-9]*\|,[0-9]\)[ ]\([0-9][0-9]*:[0-9][0-9]*\|[0-9][/]\)/\1,\2/g' file
0/1:-1,-1,-1:146:28:14,14:4,0,0/1:-1,-1,-1:134:6:2,2:1,0

如果文件中还有其他警告,建议您输入几行完整的输入内容,如果它们太长,请创建一个zip,gzip,bzip或xz文件,并将其发布到pastebin之类的站点并添加您问题的链接。

如果您现在真正关心的只是,0 0/中的空格,那么可以将sed命令缩短为:

$ sed 's/\(,[0-9]\)[[:space:]]\([0-9][/]\)/\1,\2/g' file
0/1:-1,-1,-1:146:28:14,14:4,0,0/1:-1,-1,-1:134:6:2,2:1,0

注意:),我在其中包含[[:space:]]来处理任何空格(空格,制表符,...),而不仅仅是文字[ ](空格)新示例) 让我知道是否可以解决问题。

答案 2 :(得分:0)

使用awk,您也可以不使用正则表达式来获得所需的结果:

awk '{printf "%s", $1FS$2FS$3FS$4FS$5","$6","$7; for (i=8;i<=NF;i++) printf "%s", FS$i; print ""}' input.txt

基本上,它使用默认字段分隔符(“空格”)从字段1到5输出,然后使用逗号分隔符从字段5到7输出,然后再次使用默认分隔符从字段8开始输出。

答案 3 :(得分:0)

能否请您尝试以下。这将用于打印那些正则表达式不匹配的值。同样,通过将其作为[0-9]+\.{4}等来使匹配中提到的正则表达式短一些,因为它是在旧的awk上测试过的,因此无法对其进行测试。

awk '
BEGIN{
  OFS=","
}
match($0,/GT:GL:GOF:GQ:NR:NV [0-9]+:[0-9]+:[0-9]+:[0-9]+:[0-9]+/){
  value=substr($0,RSTART!=1?1:RSTART,RSTART+RLENGTH-1)
  value1=substr($0,RSTART+RLENGTH+1)
  gsub(/[[:space:]]+/,",",value1)
  print value,value1
  next
}
1
'  Input_file

答案 4 :(得分:0)

  

perl myscript.pl'0/1:-1,-1,-1:146:28:14,14:4,0 0/1:-1,-1,-1:134:6:2 ,2:1,0'

myscript.pl,

  #!/usr/local/ActivePerl-5.20/bin/env perl
    my $input = $ARGV[0];
    $input =~ s/ /\,/g; 
    print $input, "\n";
__DATA__

输出

0/1:-1,-1,-1:146:28:14,14:4,0,0 / 1:-1,-1,-1:134:6:2,2:1 ,0

这将删除所有空格,而不仅仅是有问题的空格