我需要您的awk帮助。
我正在尝试查找在文件中复制了列$1
和$2
的行,并且其中至少有一个副本在列ref
中具有值$3
的行。如果是这样,请在新列中打印"1"
其他打印"2"
。
输入文件的示例为:
a 123 exp_a
a 123 ref
b 146 exp_a
c 156 ref
d 205 exp_a
d 205 exp_b
输出文件将是:
a 123 exp_a 1
a 123 ref 1
b 146 exp_a 2
c 156 ref 2
d 205 exp_a 2
d 205 exp_b 2
在这里,a 123
与在ref
处有$3
的一行重复,因此得到1
。相比之下,其他人要么不在$1
和$2
复制,要么在ref
没有$3
,所以得到2
。>
经过一番摆弄之后,我设法将1
和$1
重复的行放在$2
上,但是{{1} },我无法告诉awk打印ref
,否则... SPOILERS:我的代码可能非常难看。
$3
我得到的输出是:
2
答案 0 :(得分:2)
请您尝试以下。
awk 'FNR==NR{a[$1,$2]++;b[$1,$2]=$3;next} {$NF=(b[$1,$2]=="ref" && a[$1,$2]>1?$NF OFS "1":$NF OFS "2")} 1' OFS="\t" Input_file Input_file
在这里也添加非单一衬里形式的解决方案。
awk '
FNR==NR{
a[$1,$2]++
b[$1,$2]=$3
next
}
{
$NF=(b[$1,$2]=="ref" && a[$1,$2]>1?$NF OFS "1":$NF OFS "2")
}
1
' OFS="\t" Input_file Input_file
答案 1 :(得分:2)
$ cat tst.awk
BEGIN { OFS="\t" }
NR==FNR {
cnt2[$1,$2]++
cnt3[$1,$2,$3]++
next
}
{ print $0, (cnt2[$1,$2]>1 && cnt3[$1,$2,"ref"]>0 ? 1 : 2) }
$ awk -f tst.awk file file
a 123 exp_a 1
a 123 ref 1
b 146 exp_a 2
c 156 ref 2
d 205 exp_a 2
d 205 exp_b 2
答案 2 :(得分:0)
该数据仅用一次即可处理,但是希望文件由“ {key}” $1 $2
排序。每个“键”组中的记录以随机顺序(for(i in a)
)输出:
awk '
BEGIN { FS=OFS="\t" }
{
if((p!=$1 OFS $2) && NR>1) { # when the $1 $2 changes from previous
for(i=1;i<=a[0];i++) { # iterate and output buffered records
print p,a[i],2-(a[-1]&&a[0]>1) # more than one record in buffer and ...
} # ... ref for $4=1
delete a # empty buffer after output
}
if($3=="ref") # if there is a match in $3
a[-1]++ # increase counter
a[++a[0]]=$3 # buffer records to a, a[0] counter
p=$1 OFS $2 # p is for previous "key"
}
END {
for(i=1;i<=a[0];i++) # duplicate code from above if
print p,a[i],2-(a[-1]&&a[0]>1)
}' file
输出:
a 123 exp_a 1
a 123 ref 1
b 146 exp_a 2
c 156 ref 2
d 205 exp_a 2
d 205 exp_b 2
记录计数器a[0]
和引用计数器a[-1]
位于a[]
中,以单个delete a
对其进行重置。