我有fileA.txt,下面显示了几行:
AA
BB
CC
DD
EE
我有fileB.txt,它的文字如下所示:
Group col2 col3 col4
1 pp 4567 AA,BC,AB
1 qp 3428 AA
2 pp 3892 AA
3 ee 28399 AA
4 dd 3829 BB,CC
1 dd 27819 BB
5 ak 29938 CC
对于fileA.txt中的每一行,它应该根据fileB.txt中的column1计算它在fileB.txt中的存在次数。
示例输出应如下所示:
AA 3
BB 2
CC 2
AA存在4次,但它在组“1”中存在两次。如果它在column1中的同一组中出现多次,则只应计数一次,因此在上面的输出中AA计数为3.
使用awk或任何其他oneliners的任何帮助?
答案 0 :(得分:1)
这是一个应该有效的awk
单行:
awk '
NR==FNR && !seen[$4,$1]++{count[$4]++;next}
($1 in count){print $1,count[$1]}' fileB.txt fileA.txt
阐释:
NR==FNR&&!seen[$4,$1]++
模式仅在第1列未被捕获时才为真。对于所有重复捕获,我们不增加计数器。 $1 in count
在数组中查找第一个文件列1的存在。如果它存在,我们打印计数。 输出
$ awk 'NR==FNR && !seen[$4,$1]++{count[$4]++;next}($1 in count){print $1,count[$1]}' fileB.txt fileA.txt
AA 3
BB 2
CC 1
awk '
NR==FNR {
n = split($4,tmp,/,/);
for(x = 1; x <= n; x++) {
if(!seen[$1,tmp[x]]++) {
count[tmp[x]]++
}
}
next
}
($1 in count) {
print $1, count[$1]
}' fileB.txt fileA.txt
<强>输出:强>
AA 3
BB 2
CC 2
答案 1 :(得分:0)
Pure bash(4.0或更新版):
#!/bin/bash
declare -A items=()
# read in the list of items to track
while read -r; do items[$REPLY]=0; done <fileA.txt
# read fourth column from fileB and increment for each match
while read -r _ _ _ item _; do
[[ ${items[$item]} ]] || continue # skip unrecognized values
items[$item]=$(( items[$item] + 1 )) # otherwise, increment
done <fileB.txt
# print output
for key in "${!items[@]}"; do # iterate over keys
value="${items[$key]}" # look up values
printf '%s\t%s\n' "$key" "$value" # print them together
done
答案 2 :(得分:0)
一个简单的awk单行。
awk 'NR>FNR{if($0 in a)print$0,a[$0];next}!a[$4,$1]++{a[$4]++}' fileB.txt fileA.txt
请注意文件的顺序。