You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

bash下快速修改多列取值相同的行的指定字段的方法

解决方案

你可以直接用awk两次扫描文件实现需求,全程只需要读取两次文件,不需要循环多次IO,处理10000+行的文件几乎是瞬间完成:

基础版命令(适配空白分隔的文件)

awk 'NR==FNR {
    cnt[$1,$4,$5]++
    next
}
cnt[$1,$4,$5] >= 2 {
    $2 = 0
}
1' input.txt input.txt

逻辑说明

  • 第一次读取文件时(NR==FNR判断成立,NR是全局行号,FNR是当前文件的行号,首次读取时二者相等),以第1、4、5列的组合为键统计出现次数,统计完成后直接跳过后续逻辑处理下一行。
  • 第二次读取文件时,判断当前行的1、4、5列组合的出现次数是否≥2,是的话将第2列赋值为0。
  • 末尾的1是awk的固定写法,作用是打印所有处理后的行。

格式保留版(适配制表符分隔/需要严格保留原有列间隔的场景)

如果你的文件是制表符分隔,需要保留输出的列格式,加上OFS(输出字段分隔符)设置即可:

awk 'BEGIN{OFS="\t"} NR==FNR{cnt[$1,$4,$5]++;next} cnt[$1,$4,$5]>=2{$2=0}1' input.txt input.txt

Perl单行实现

如果你更习惯用perl,也可以用下面的单行脚本实现相同逻辑:

perl -ane 'if ($. == $ARGC) {
    $k = join "\0", $F[0], $F[3], $F[4];
    $F[1] = 0 if $cnt{$k} >=2;
    print join "\t", @F, "\n";
} else {
    $k = join "\0", $F[0], $F[3], $F[4];
    $cnt{$k}++;
}' input.txt input.txt

说明

perl的-a参数会自动将每行按空白分割到@F数组中,数组下标从0开始,所以第1列对应$F[0]、第4列对应$F[3]、第5列对应$F[4],逻辑和awk版本完全一致。

内容的提问来源于stack exchange,提问作者matheusb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 06:21:01