Is there a way to completely delete fields in awk, so that extra delimiters do not print?

后端 未结 9 1072
醉话见心
醉话见心 2020-12-20 12:52

Consider the following command:

$ gawk -F"\\t" "BEGIN{OFS=\\"\\t\\"}{$2=$3=\\"\\"; p         


        
相关标签:
9条回答
  • 2020-12-20 13:25

    If you are just looking to remove columns, you can use cut:

    $ cut -f 1,4- file.txt
    

    To emulate 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
    

    Similarly:

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

    HTH

    0 讨论(0)
  • 2020-12-20 13:28

    This is an oldie but goodie.

    As Jonathan points out, you can't delete fields in the middle, but you can replace their contents with the contents of other fields. And you can make a reusable function to handle the deletion for you.

    $ 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
    
    0 讨论(0)
  • 2020-12-20 13:28

    The method presented in the answer of ghoti has some problems:

    • every assignment of $i = $(i+1) forces awk to rebuild the record $0. This implies that if you have 100 fields and you want to delete field 10, you rebuild the record 90 times.

    • changing the value of NF manually is not posix compliant and leads to undefined behaviour (as is mentioned in the comments).

    A somewhat more cumbersome, but stable robust way to delete a set of columns would be:

    a single column:

    awk -v del=3 '
        BEGIN{FS=fs;OFS=ofs}
        { b=""; for(i=1;i<=NF;++i) if(i!=del) b=(b?b OFS:"") $i; $0=b }
        # do whatever you want to do
       ' file
    

    multiple columns:

    awk -v del=3,5,7 '
        BEGIN{FS=fs;OFS=ofs; del="," del ","}
        { b=""; for(i=1;i<=NF;++i) if (del !~ ","i",") b=(b?b OFS:"") $i; $0=b }
        # do whatever you want to do
       ' file
    
    0 讨论(0)
提交回复
热议问题