如何用awk在连续两行第三列值不同时插入分隔符
解决awk处理行分隔符的问题
咱们先看看你原来的awk代码为啥不生效:
你的代码awk '{col3=$3;next} $3!=col3{$0="\n="$0;print $0}' input有两个致命问题:
- 用了
next之后,当前行的打印操作直接被跳过了,第一行根本不会输出,后续行的处理逻辑也完全混乱; - 你没有保存上一行的内容,也没找对打印的时机,只是在判断当前行和上一行第三列不同时修改当前行,这完全达不到你想要的在目标行末尾加分隔符的效果。
符合你预期结果的解决方案
从你给出的预期输出来看,你实际需要的是:当某一行没有第三列(列数<3),且下一行有第三列(列数>=3)时,在当前行末尾加上 =。对应的awk代码如下:
NR==1 {prev=$0; prev_nf=NF; next} { if (prev_nf < 3 && NF >=3) { print prev " =" } else { print prev } prev=$0; prev_nf=NF } END {print prev}
把这段代码跑在你的输入数据上,就能得到你想要的结果:
one two three
four five six
three seven =
eight nine ten
elevel alpha beta
ten gama =
tango charlie oscar bla
代码逻辑说明
- 第一行单独处理:保存第一行的内容和列数,跳过后续步骤;
- 从第二行开始,先对比上一行和当前行的列数:如果上一行列数不足3、当前行列数≥3,就给上一行末尾加
=再打印,否则直接打印上一行; - 每次处理完都更新保存的上一行内容和列数;
- 最后在
END块里打印最后一行,避免遗漏。
如果严格按你描述的需求处理
如果你确实是想只要连续两行的第三列值不同(空值和非空值也算不同),就在前一行末尾加 =,可以用下面的代码:
NR==1 {prev=$0; prev_col3=$3; next} { if ($3 != prev_col3) { print prev " =" } else { print prev } prev=$0; prev_col3=$3 } END {print prev}
不过这个代码跑出来的结果会和你的预期不符,因为每一行和下一行的第三列都不一样,所以除了最后一行,其他行末尾都会加 =。
内容的提问来源于stack exchange,提问作者monk
相关产品推荐
相关产品推荐

