如何在AWK/gawk中删除输入字段且避免多余分隔符?
优雅删除awk字段并保持输出格式的方法
嘿,这个问题我太懂了——直接给字段赋值空字符串确实会搞出多余分隔符,挨个打印字段又太麻烦,尤其是字段多还有可选末尾字段的时候。给你两个实用的办法,都能靠print $0输出干净的结果:
通用字段前移法(适用于所有awk版本)
这是最稳妥的方案,不管你用的是awk还是gawk,也不管字段分隔符是逗号、空格还是其他,都能完美工作。核心思路是把要删除字段后面的所有字段往前挪一位,然后减少字段总数NF,这样awk会自动用OFS重新拼接$0,不会留空分隔符。
比如你要删除第2个字段,代码可以这么写:
BEGIN { FS=OFS="," } # 这里根据你的实际分隔符调整,默认是空白的话可以省略BEGIN块 { # 把第2个字段后面的所有字段依次前移一位 for (i=2; i<NF; i++) { $i = $(i+1) } NF-- # 去掉最后一个重复的字段,调整总字段数 print $0 }
举个例子,输入是apple,banana,cherry,date,运行后输出就是apple,cherry,date,完全没有多余逗号。如果是空白分隔的输入a b c d,输出就是a c d,也不会有多余空格。
要是你想删除任意位置的字段,比如第3个,只需要把循环里的i=2改成i=3就行,非常灵活。
gawk专属的数组操作法(gawk 4.0+可用)
如果你用的是gawk(GNU awk),可以借助数组来操作字段,可读性更强:
BEGIN { FS=OFS="," } { split($0, arr, FS) # 把$0拆成数组arr delete arr[2] # 删除第2个元素 # 重新构建$0:按顺序拼接数组元素 $0 = "" for (i=1; i<=NF; i++) { if (arr[i] != "") { $0 = $0 ($0 ? OFS : "") arr[i] } } print $0 }
不过这个方法需要额外处理元素顺序,不如第一个方法简洁,所以更推荐通用的字段前移法。
总结一下:字段前移+NF--的方式既不用挨个列字段,又能保证输出格式干净,完美解决你的需求~
内容的提问来源于stack exchange,提问作者MLu
相关产品推荐
相关产品推荐

