Awk 如何在一行中打印重复键列的字段
我想以这样一种方式转换一个表,以便复制 第#2列中的值它将具有第#1列中的相应值 也就是说,像这样的事情Awk 如何在一行中打印重复键列的字段,awk,Awk,我想以这样一种方式转换一个表,以便复制 第#2列中的值它将具有第#1列中的相应值 也就是说,像这样的事情 MZ00024296 AC148152.3_FG005 MZ00047079 AC148152.3_FG006 MZ00028122 AC148152.3_FG008 MZ00032922 AC148152.3_FG008 MZ00048218 AC148152.3_FG008 MZ00024680 AC148167.6_FG001 MZ00013456 AC149
MZ00024296 AC148152.3_FG005
MZ00047079 AC148152.3_FG006
MZ00028122 AC148152.3_FG008
MZ00032922 AC148152.3_FG008
MZ00048218 AC148152.3_FG008
MZ00024680 AC148167.6_FG001
MZ00013456 AC149475.2_FG003
到
由于需要在R中进行计算,我尝试使用:
x=aggregate(mz_grmz,by=list(mz_grmz[,2]),FUN=paste(mz_grmz[,1],sep="|"))
但它不工作(功能错误)
匹配中出错。乐趣(乐趣):
“粘贴(mz_grmz[,1],sep=“|”)不是函数、字符或符号
我还提醒自己unstack()函数,但它不是我所需要的
根据我的基本知识,我尝试使用awk来完成这项工作,我重新编写了下面给出的代码:
#/垃圾箱/垃圾箱
为了你
awk-v FS=“\t”'{
对于(x=1;x2&&x=x+1){
打印$2“\t”x
}
else{print NR}
}
}“$y>$y.2
完成
不幸的是,它不起作用,它只能生成包含字段#2和一些数字的巨大文件
我想这是一项容易的任务,但现在我的能力还不够。
谁能给我一个提示吗?也许只是在R中聚合使用的函数
谢谢您可以在awk中这样做:
awk '
{
if ($2 in a)
a[$2] = a[$2] "|" $1
else
a[$2] = $1
}
END {
for (i in a)
print i, a[i]
}' INFILE > OUTFILE
要使输出与问题中的文本保持一致(空行等): 测试:
kent$ echo "MZ00024296 AC148152.3_FG005
MZ00047079 AC148152.3_FG006
MZ00028122 AC148152.3_FG008
MZ00032922 AC148152.3_FG008
MZ00048218 AC148152.3_FG008
MZ00024680 AC148167.6_FG001
MZ00013456 AC149475.2_FG003"|awk '{if($0 &&($2 in a))a[$2]=a[$2]"|"$1;else if ($0) a[$2]=$1;}END{for(x in a){print x,a[x];print ""}}'
AC149475.2_FG003 MZ00013456
AC148152.3_FG005 MZ00024296
AC148152.3_FG006 MZ00047079
AC148152.3_FG008 MZ00028122|MZ00032922|MZ00048218
AC148167.6_FG001 MZ00024680
此GNU-sed解决方案可能适合您:
sed -r '1{h;d};H;${x;s/(\S+)\s+(\S+)/\2\t\1/g;:a;s/(\S+\t)([^\n]*)(\n+)\1([^\n]*)\n*/\1\2|\4\3/;ta;p};d' input_file
说明:使用扩展正则表达式选项
-r
使正则表达式更具可读性。将整个文件读入保持空间(HS)。然后在文件末尾,切换到HS,首先交换和制表符单独的字段。然后比较相邻行中的第一个字段,如果它们匹配,则将第二条记录中的第二个字段标记为第一行,并用
分隔。重复,直到没有其他相邻行具有重复的第一个字段,然后打印文件。空行可能会在输出中出现问题。我没有测试,但我可以看到,输出中应该有“| | |…”。顺便说一句,你的声誉号码很好:)4444@Kent我假设空行是复制粘贴工件。如果没有,这可以通过在第一个{
.schot,Kent之前添加NF
来轻松解决。谢谢你们两个。它可以工作:-)。空行确实是一个工件。如果不是,我会在主脚本之前使用sed'/^$/d删除它。谢谢Poton的回复。你的代码要么不工作,要么我的计算机(2 x 1.5 GHz,2Gb RAM)太弱了。我已经提交了它,我的系统监视器显示代码正在运行,但大约30分钟后。没有任何变化,所以我终止了进程。无论如何-谢谢你的时间。我检查了较小的文件,它可以工作。它只是比awk代码慢得多。
awk '{if($0 &&($2 in a))a[$2]=a[$2]"|"$1;else if ($0) a[$2]=$1;}\
END{for(x in a){print x,a[x];print ""}}' inputFile
kent$ echo "MZ00024296 AC148152.3_FG005
MZ00047079 AC148152.3_FG006
MZ00028122 AC148152.3_FG008
MZ00032922 AC148152.3_FG008
MZ00048218 AC148152.3_FG008
MZ00024680 AC148167.6_FG001
MZ00013456 AC149475.2_FG003"|awk '{if($0 &&($2 in a))a[$2]=a[$2]"|"$1;else if ($0) a[$2]=$1;}END{for(x in a){print x,a[x];print ""}}'
AC149475.2_FG003 MZ00013456
AC148152.3_FG005 MZ00024296
AC148152.3_FG006 MZ00047079
AC148152.3_FG008 MZ00028122|MZ00032922|MZ00048218
AC148167.6_FG001 MZ00024680
sed -r '1{h;d};H;${x;s/(\S+)\s+(\S+)/\2\t\1/g;:a;s/(\S+\t)([^\n]*)(\n+)\1([^\n]*)\n*/\1\2|\4\3/;ta;p};d' input_file