Search code examples
shellawk

Print all but the first three columns


Too cumbersome:

awk '{print " "$4" "$5" "$6" "$7" "$8" "$9" "$10" "$11" "$12" "$13}' things

Solution

  • A solution that does not add extra leading or trailing whitespace:

    awk '{ for(i=4; i<NF; i++) printf "%s",$i OFS; if(NF) printf "%s",$NF; printf ORS}'
    
    ### Example ###
    $ echo '1 2 3 4 5 6 7' |
      awk '{for(i=4;i<NF;i++)printf"%s",$i OFS;if(NF)printf"%s",$NF;printf ORS}' |
      tr ' ' '-'
    4-5-6-7
    

    Sudo_O proposes an elegant improvement using the ternary operator NF?ORS:OFS

    $ echo '1 2 3 4 5 6 7' |
      awk '{ for(i=4; i<=NF; i++) printf "%s",$i (i==NF?ORS:OFS) }' |
      tr ' ' '-'
    4-5-6-7
    

    EdMorton gives a solution preserving original whitespaces between fields:

    $ echo '1   2 3 4   5    6 7' |
      awk '{ sub(/([^ ]+ +){3}/,"") }1' |
      tr ' ' '-'
    4---5----6-7
    

    BinaryZebra also provides two awesome solutions:
    (these solutions even preserve trailing spaces from original string)

    $ echo -e ' 1   2\t \t3     4   5   6 7 \t 8\t ' |
      awk -v n=3 '{ for ( i=1; i<=n; i++) { sub("^["FS"]*[^"FS"]+["FS"]+","",$0);} } 1 ' |
      sed 's/ /./g;s/\t/->/g;s/^/"/;s/$/"/'
    "4...5...6.7.->.8->."
    
    $ echo -e ' 1   2\t \t3     4   5   6 7 \t 8\t ' |
      awk -v n=3 '{ print gensub("["FS"]*([^"FS"]+["FS"]+){"n"}","",1); }' |
      sed 's/ /./g;s/\t/->/g;s/^/"/;s/$/"/'
    "4...5...6.7.->.8->."
    

    The solution given by larsr in the comments is almost correct:

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

    This is the fixed and parametrized version of larsr solution:

    $ echo '1 2 3 4 5 6 7' | 
      awk '{for(i=n;i<=NF;i++)$(i-(n-1))=$i;NF=NF-(n-1);print $0}' n=4 | tr ' ' '-'
    4-5-6-7
    

    All other answers before Sep-2013 are nice but add extra spaces: