chr:pos1:pos2 Sun NC S1 S2 S3 S4 S9 S11 S14 S15 S16 S17 S18 S19 S28 S29 S30 S33 S34 S35 S36 S37 S38 S39
Aradu.A01:100145549:100145556 AG AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA
Aradu.A01:100408119:100408137 CA TA 0 0 0 TA TA TA TA TA TA TA TA TA TA TA TA TA TA TA TA 0
Aradu.A01:10102206:10102212 TG TA TA TA TA 0 TG TA TA TA TG TG TG TG TG TA TG TG TA 0 TG TG
Aradu.A01:10112010:10112029 GA GG GG GG GG GG GA GG GG GG GA 0 GA GA GA GG GA GA GG GA 0 GA
Aradu.A01:10112029:10112059 AC GC GC GC GC GC AC GC GC GC AC 0 AC AC AC GC AC 0 GC AC 0 AC
Aradu.A01:101198026:101198058 GT GC GC GC GT GC 0 GT GT GC GT GT GT 0 GT GC GT GC GC GT 0 GT
Aradu.A01:101198058:101198081 TC CC CC CC TC CC 0 TC TC CC TC TC TC 0 TC CC TC CC CC TC 0 TC
Aradu.A01:101306922:101306946 AG AA AA AA AG 0 AA AG AG AA 0 AG AG AG AG AA AG AG AA AG AG AG
在给定的文件中,我尝试将第 4 列及以后的所有字段中的值与第 2 列和第 3 列相匹配。如果字段(第 4 列及以后)的值与第 2 列字段匹配,则将其标记为 S(如果匹配)与 col 3 然后将其标记为 N,如果它是 0,则将其分配为 -1。
以下是我尝试过的:
NR>1 {for(i=4;i<=NF;i++)
{ if ( $i == $2 ) $i=S ;
if ( $i == $3 ) $i=N ;
if ( $i == 0 ) $i=-1 ;
} ## if ;
## for loop is done
print ;
}
这会导致将除前 3 个字段之外的所有字段分配为 -1。
答案1
这似乎可以解决问题:
NR > 1 {
for( i=4; i<NF; i++) {
if( $i == $2 ) {
$i = "S"
}
else if( $i == $3 ) {
$i = "N"
}
else if( $i == 0 ) {
$i = -1
}
}
print
}
将其放入名为 eg 的文件中363142.awk
,然后运行:
$ awk -f 363142.awk /path/to/input
答案2
perl -F\\s+ -pale '
$. > 1 and /(?:\S+\s+){3}/g and
s{\G(\S+)(\s*)}
{
($1 eq $F[1] ? "S" : $1 eq $F[2] ? "N" : $1 eq "0" ? -1 : $1) . $2
}cge;
' your_genes_file
选项
-F\\s+
将设置FS
为一个或多个空格=>/\s+/
-p
将设置一个隐式文件循环读取并且打印是自动的。-a
将根据-F
选项提供的字段分割分隔符或默认的单个空格重新分割每条记录。这些字段存储在数组中@F
。-l
将设置ORS=RS=\n
-e
是Perl
要应用于每条记录的代码。
解释
我们跳过处理的第一行。-p
选项将小心打印它。然后我们将正则表达式引擎标记停放在第四个字段的开头,因为那是所有操作应该开始的地方。然后我们在、、 和模式下应用该s///
命令。=> 正则表达式标记将从最后一个命令中停放的位置开始,而不是从开头开始。=> 将查看整行以对其进行转换,并将替换部分视为要执行的代码,其结果将停放在替换部分中。global
cumulative
eval
/c
m//g
/g
/e
s//repl/
Perl
GNU sed
可以将其写入,POSIX sed
但这样代码会妨碍清晰度,因此只能作为适度的练习。
sed -e '
1b
# fence the column 2 and go looking for col2 matching fields from col 4 onwards
s/\S\+/\n&\n/2
:c2
s/\(\n\(.*\)\n\s\+\S\+\s.*\)\<\2\>/\1S/g;tc2
s/\n//g
# fence the column 3 and go looking for col3 matching fields from col 4 onwards
s/\S\+/\n&\n/3
:c3
s/\(\n\(.*\)\n.*\)\<\2\>/\1N/g;tc3
s/\n//
# from col 4 onwards look for any lone 0s and change them to -1
:zm1
s/\(\n.*\)\<0\>/\1-1/;tzm1
s/\n//
' gene_file.dat
珀尔
在这里,我们删除任何会干扰 @F 数组索引的前导空格,然后在打印数据时恢复它。我们map
将元素 6 向前(空格为 4+2)并检查它们是否等于第 2/3 列或 0。
perl -F'(\s+)' -lane '
print,next if $. == 1;
my $dummy = splice @F, 0, 2 if /^\h/;
print $dummy, @F[0..5], map {
s/^\Q$F[2]\E$/S/ or s/^\Q$F[4]\E$/N/ or s/^0$/-1/; $_
} @F[6 .. $#F];
' gene_file.dat