我有一个文件(;分开),包含这样的数据
111111121;000-000.1;000-000.2
111111211;000-000.1;000-000.2
111112111;000-000.1;000-000.2
111121111;000-000.1;000-000.2
111211111;000-000.1;000-000.2
112111111;000-000.1;000-000.2
121111112;000-000.2;020-000.8
121111121;000-000.2;020-000.8
121111211;000-000.2;020-000.8
121113111;000-000.3;000-200.2
211111121;000-000.1;000-000.2
我想删除任何少于3次出现的3美元,所以结果就像
111111121;000-000.1;000-000.2
111111211;000-000.1;000-000.2
111112111;000-000.1;000-000.2
111121111;000-000.1;000-000.2
111211111;000-000.1;000-000.2
112111111;000-000.1;000-000.2
121111112;000-000.2;020-000.8
121111121;000-000.2;020-000.8
121111211;000-000.2;020-000.8
121113111;000-000.3
211111121;000-000.1;000-000.2
也就是说,只有3美元被删除了,因为它只有一次出现
可悲的是,我不确定是否(因此如何)这可以相对容易地完成(因为做= COUNT.IF匹配,并且Excel中的manuel删除感觉非常尴尬)
答案 0 :(得分:0)
您可以将文件两次送到awk。在第一次运行时,您将收集在第二次运行中使用的统计信息:
<强> script.awk 强>
FNR == NR { stats[ $3 ]++
next
}
{ if( stats[$3] < 3) print $1 $2
else print
}
像这样运行:awk -F\; -f script.awk yourfile yourfile
。
在处理给予awk的第一个文件名时,条件FNR == NR
为真。 next
语句跳过第二个块。
因此第二个块仅用于处理给予awk的第二个文件名(这里与第一个文件名相同)。
答案 1 :(得分:0)
这个awk单行可以提供帮助,它会对文件进行两次处理:
awk -F';' 'NR==FNR{a[$3]++;next}a[$3]<3{NF--}7' file file
答案 2 :(得分:0)
$ awk -F';' 'NR==FNR{cnt[$3]++;next} cnt[$3]<3{sub(/;[^;]+$/,"")} 1' file file
111111121;000-000.1;000-000.2
111111211;000-000.1;000-000.2
111112111;000-000.1;000-000.2
111121111;000-000.1;000-000.2
111211111;000-000.1;000-000.2
112111111;000-000.1;000-000.2
121111112;000-000.2;020-000.8
121111121;000-000.2;020-000.8
121111211;000-000.2;020-000.8
121113111;000-000.3
211111121;000-000.1;000-000.2
或者如果您愿意:
$ awk -F';' 'NR==FNR{cnt[$3]++;next} {print (cnt[$3]<3 ? $1 FS $2 : $0)}' file file
答案 3 :(得分:0)
虽然awk解决方案在性能方面是最好的,但您的目标也可以通过以下方式实现:
while IFS=" " read a b;do
if [[ "$a" -lt "3" ]];then
sed -i "s/$b//" b.txt
fi
done <<<"$(cut -d";" -f3 b.txt |sort |uniq -c)"
操作基于切割输出,用于计算出现次数。
$cut -d";" -f3 b.txt |sort |uniq -c
7 000-000.2
1 000-200.2
3 020-000.8
以上版本适用于编辑源文件,因此请备份以进行测试。