有没有办法完全删除awk中的字段,以便不打印额外的分隔符?

mer*_*011 13 awk gawk

请考虑以下命令:

gawk -F"\t" "BEGIN{OFS=\"\t\"}{$2=$3=\"\"; print $0}" Input.tsv
Run Code Online (Sandbox Code Playgroud)

当我设置$ 2 = $ 3 =""时,获得与写入相同效果的预期效果:

print $1,$4,$5...$NF
Run Code Online (Sandbox Code Playgroud)

然而,实际发生的是我得到两个空字段,额外的字段分隔符仍在打印.

是否有可能实际删除2美元和3美元?

注意:如果这是在Linux上bash,上面的正确语句如下,但Windows不能很好地处理单引号cmd.exe.

gawk -F'\t' 'BEGIN{OFS="\t"}{$2=$3=""; print $0}' Input.tsv
Run Code Online (Sandbox Code Playgroud)

Jon*_*ely 8

您不能删除中间的字段,但可以通过递减删除最后的字段NF.

所以,你可以关闭所有的后场转移到覆盖$2$3随后递减NF两部分,可清除最后两个字段:

$ echo 1 2 3 4 5 6 7 | awk '{for(i=2; i<NF-1; ++i) $i=$(i+2); NF-=2; print $0}'
1 4 5 6 7
Run Code Online (Sandbox Code Playgroud)


gho*_*oti 7

这是一个老人,但好.

正如Jonathan指出的那样,你不能删除中间的字段,但可以用其他字段的内容替换它们的内容.并且您可以创建一个可重用的函数来为您处理删除.

$ cat test.awk
function rmcol(col,     i) {
  for (i=col; i<NF; i++) {
    $i=$(i+1)
  }
  NF--
}

{
  rmcol(3)
}

1

$ printf 'one two three four\ntest red green blue\n' | awk -f test.awk
one two four
test red blue
Run Code Online (Sandbox Code Playgroud)

  • 递减 NF 是每个 POSIX 的未定义行为。它将删除某些 awk 中的最后一个字段,在其他 awk 中被忽略,并且可以做任何其他事情并且仍然符合 POSIX。 (2认同)
  • `回声'abc' | awk '{$1=$1;NF--}1'` 产生相同的输出 `ab`。**未定义**行为确实 - 莫名其妙可能是一个更好的术语!:-)。 (2认同)

Ste*_*eve 5

如果您只是想删除列,则可以使用cut

$ cut -f 1,4- file.txt
Run Code Online (Sandbox Code Playgroud)

模仿cut

$ awk -F "\t" '{ for (i=1; i<=NF; i++) if (i != 2 && i != 3) { if (i == NF) printf $i"\n"; else printf $i"\t" } }' file.txt
Run Code Online (Sandbox Code Playgroud)

相似地:

$ awk -F "\t" '{ for (i=1; i<=NF; i++) if (i != 2 && i != 3) { if (i == NF) printf $i"\n"; else printf $i"\t" } }' file.txt
Run Code Online (Sandbox Code Playgroud)

HTH