我有一个数据文件A.tsv
(字段分隔符= \t
):
id clade mutation
243 40A S:ojo,L:juju,S:lili
254
267 40B J:jijy,S:asel,M:ase
我想在另一列(在新文件中B.tsv
)仅打印以 开头的突变S:
,如下所示:
id clade mutation S_mutation
243 40A S:ojo,L:juju,S:lili S:ojo,S:lili
254
267 40B J:jijy,S:asel,M:ase S:asel
我用 awk 尝试了一些命令,但没有结果:
awk -F '\t' 'BEGIN { OFS = FS } NR==1 {$(NF+1)="S_Mutation"} ; NR != 1 { $4 = ($3==^[Ss] ? $4 ) }; 1' A.tsv > B.tsv
你知道该怎么做吗?谢谢
答案1
有了POSIX awk
,我们就可以如图所示进行操作。将第三个字段用逗号拆分为行 >1 并选择以 S: 开头的元素,然后用逗号将它们连接起来,使其成为最后+1 字段。
awk -F '\t' '
BEGIN {
OFS = FS
_SEP_ = ","
}
NR==1{$(NF+1) = "S_mutation"}
NR>1&&length($3)>0{
nf = split($3, a, _SEP_)
t = ""
for (i=1; i<=nf; i++) {
if (a[i] ~ /^S:/) {
t = t (t=="" ? t : _SEP_) a[i]
}
}
$(NF+1) = t
}1
' file
同样的事情Perl
,但使用正则表达式
perl -lnse '$,="\t";
print $_,($.==1?q(S_mutation):
"@{[/(?:\t|,)\KS:[^,]*/g]}"||());
' -- -\"=, ./file
输出:
id clade mutation S-mutation
243 40A S:ojo,L:juju,S:lili S:ojo,S:lili
254
267 40B J:jijy,S:asel,M:ase S:asel
答案2
使用awk
(POSIX)。
awk -F "\t" '
BEGIN { OFS = FS }
NR == 1 { $4 = "S_Mutation" }
NR > 1 && NF == 3 {
printf "%s", $0 "\t"
$0 = $3
gsub(/[^S]:[^,]*,?/, "")
sub(/,$/, "")
print $1
next
}
1' data.txt
- 如果行 > 1 且字段数 = 3
- 打印行,不带尾随换行符
- 设置行 = 字段 3
- 删除不以以下字符开头的字符串
S:
- 删除所有结尾的逗号
- 打印带换行符的字段
- 处理下一行
- 别的
- 打印线
您可能不想打印尾随选项卡,测试$1
替换后是否有任何内容,然后打印TAB
+ 字段。 (如果您不想在没有S:xxx
字段的行上使用尾随制表符。例如:
# Print line
printf "%s", $0
# Set line = field 3
$0 = $3
# Replace all N:xxx where N is not S
gsub(/[^S]:[^,]*,?/, "")
# Remove trailing comma
sub(/,$/, "")
# Print the field
if ($1 != "")
print "\t"$1
else
print ""
# Continue with next line
next
答案3
使用 Perl
perl -F'\t' -lpe '
push @F, $. == 1 ? "S_mutation" : join ",", grep { /^S:/ } split /,/, $F[2];
$_ = join "\t", @F
' A.tsv > B.tsv
前任。
$ perl -F'\t' -lpe '
push @F, $. == 1 ? "S_mutation" : join ",", grep { /^S:/ } split /,/, $F[2];
$_ = join "\t", @F
' A.tsv | column -t
id clade mutation S_mutation
243 40A S:ojo,L:juju,S:lili S:ojo,S:lili
254
267 40B J:jijy,S:asel,M:ase S:asel
答案4
如果您不介意使用sed
:
sed 'h;s/.*[[:space:]]/,/;s/,[^S]:[^,]*//g;x;G;s/\n,/\t/'
请注意,\t
仅适用于 GNU sed
。对于其他风格,通常通过输入ctrlv然后按 Tab 键来插入文字选项卡。
其概念是将行保存在保留空间中,然后隔离最后一列并删除除突变之外的所有突变S:
。然后将其作为最后一列附加到保存的行:
h
将该行复制到保留空间s/.*[[:space:]]/,/
用逗号替换最后一个制表符或空格之前的所有内容,因此保留最后一列,并在前面添加逗号。这个逗号将有助于下一步s/,[^S]:[^,]*//g
S:
删除除 之外的所有元素x
交换持有空间和模式空间,因此G
会将新列附加到保留空间中保留的原始列s/\n,/\t/
最后替换了附加的换行符和我们通过制表符引入的逗号