Awk 根据出现次数删除列的内容

Awk 根据出现次数删除列的内容,awk,sed,Awk,Sed,我有一个文件(;分隔)包含这样的数据 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;0

我有一个文件(;分隔)包含这样的数据

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 delete感到非常尴尬)

您可以将文件两次馈送给awk。在第一次运行中,您收集了在第二次运行中使用的统计数据:

script.awk

FNR == NR { stats[ $3 ]++
            next
          }

          { if( stats[$3] < 3) print $1 $2
            else print
          }
FNR==NR{stats[$3]++
下一个
}
{如果(统计数据[$3]<3)打印$1$2
其他打印
}
像这样运行:
awk-F\-f script.awk yourfile yourfile

在处理给awk的第一个文件名期间,条件
FNR==NR
为真。
next
语句跳过第二个块


因此,第二个块仅用于处理给定给awk的第二个文件名(此处与第一个文件名相同)。

您可以将文件两次馈送给awk。在第一次运行中,您收集了在第二次运行中使用的统计数据:

script.awk

FNR == NR { stats[ $3 ]++
            next
          }

          { if( stats[$3] < 3) print $1 $2
            else print
          }
FNR==NR{stats[$3]++
下一个
}
{如果(统计数据[$3]<3)打印$1$2
其他打印
}
像这样运行:
awk-F\-f script.awk yourfile yourfile

在处理给awk的第一个文件名期间,条件
FNR==NR
为真。
next
语句跳过第二个块


因此,第二个块仅用于处理给定给awk的第二个文件名(此处与第一个文件名相同)。

此awk一行程序有帮助,它处理文件两次:

awk -F';' 'NR==FNR{a[$3]++;next}a[$3]<3{NF--}7' file file

awk-F';“”NR==FNR{a[$3]++;next}a[$3]此awk单行程序可能会有所帮助,它会处理文件两次:

awk -F';' 'NR==FNR{a[$3]++;next}a[$3]<3{NF--}7' file file

awk-F';“”NR==FNR{a[$3]+;next}a[$3]
$awk-F';''NR==FNR{cnt[$3]+;next}cnt[$3]
$awk-F';''NR==FNR{cnt[$3]++;next}cnt[$3]虽然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)"

上面的工作是就地编辑源文件,因此请为测试做好备份。

尽管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)"

上面的工作是在适当的位置编辑源文件,因此为测试保留一个备份。

YMMV with
NF--
,因为这是POSIX中未定义的行为,所以不同的AWK将对其执行不同的操作(很可能忽略它或删除最后一个字段).YMMV和
NF--
因为这是POSIX中未定义的行为,所以不同的AWK将使用它做不同的事情(很可能忽略它或删除最后一个字段)。非常感谢您提供的优雅解决方案!(对于我迟来的回复,我真的非常抱歉……)非常感谢您提供的优雅解决方案!(对于我迟来的答复,我真的非常抱歉……)