我有一个包含 5 个字段的基因型文件(第 5 个字段宽度= 200000 个值 [零和一]):
MA,30009,4,4,000010000111101011111000110100000000 .......
ME,30067,3,2,000010000111101011111000110100000000 .......
MI,30032,7,8,000010000111101011111000110100000000 .......
我想将最后一个字段分成多列,每 2 个值 (ncol = 100000)。我希望输出如下:
MA,30009,4,4,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00 .......
ME,30067,3,2,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00 .......
MI,30032,7,8,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00 .......
awk?嘎嘎? sed?
有什么帮助吗?提前致谢
答案1
awk 'BEGIN{FS=OFS=","}{gsub(/../,"&,",$NF)}1' file
BEGIN{FS=OFS=","}
将字段分隔符设置为,
.{gsub(/../,"&,",$NF)}
附加,
到最后一个字段 ($NF
) 中的每 2 个字符。1
打印结果行。
结果:
MA,30009,4,4,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00,
如果您想删除上述命令生成的尾随逗号,请使用额外的sub
函数将其删除:
awk 'BEGIN{FS=OFS=","}{gsub(/../,"&,",$NF);sub(/,$/,"",$NF)}1' file
MA,30009,4,4,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00
答案2
您可以将 Sed 与循环一起使用:
$ sed -E -e :a -e 's/(,[^,]{2})([^,]{1,})$/\1,\2/;ta' file
MA,30009,4,4,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00
ME,30067,3,2,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00
MI,30032,7,8,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00
(我有一种感觉,有一种更简洁的方法可以做到这一点,从头开始$
并向后工作 - 但我不能完全确定它)。 (扩展正则表达式)模式-E
不是必需的 - 它只是简化了转义。
或者使用 Perl:
$ perl -F, -lne '$last = pop @F; print join ",", @F, $last =~ m/(..)/g' file
MA,30009,4,4,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00
ME,30067,3,2,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00
MI,30032,7,8,00,00,10,00,01,11,10,10,11,11,10,00,11,01,00,00,00,00
答案3
GNU awk 我们将最后一个字段合并到倒数第二个字段中,然后递减字段计数。
gawk -F ',' -v OFS="," '{
$4 = $4 gensub(/../, ",&", "g", $5)
}NF--' file
用 awk
awk '
BEGIN { OFS = FS = "," }
gsub(/../, FS "&", $5) {
print $1, $2, $3, $4 $5
}
' file
具有扩展模式的 GNU sed
sed -Ee '
s/,/\n/4;ta
:a
s/\n,/,/;t
s/..(,..)*$/,&/
ta
' file
在 Perl 中,我们一次解压第 5 个字段的两个字符。
perl -F, -lape '$_ = join ",", @F[0..3], unpack "(A2)*", $F[4]' file
使用 Perl 的另一种方法
perl -F, -lane 'print reverse pop(@F) =~ s/(..)/,$1/gr, join ",", @F' file
perl -lpe 's/^.*[^,]\K,(.*)/$1 =~ s|(..)|,$1|gr/e' file
在 rhs 上使用 posix sed (\n) 是象征性的。将其替换为转义换行符)
sed -e '
s/,/\n/4;h;s/\n.*//;x
s/.*\n//;s/../,&/g;H;x
s/\n//
' file