Using awk to print all columns from the nth to the

2019-01-03 00:29发布

This line worked until I had whitespace in the second field.

svn status | grep '\!' | gawk '{print $2;}' > removedProjs

is there a way to have awk print everything in $2 or greater? ($3, $4.. until we don't have anymore columns?)

I suppose I should add that I'm doing this in a Windows environment with Cygwin.

标签: linux awk
24条回答
戒情不戒烟
2楼-- · 2019-01-03 01:16
ls -la | awk '{o=$1" "$3; for (i=5; i<=NF; i++) o=o" "$i; print o }'

from this answer is not bad but the natural spacing is gone.
Please then compare it to this one:

ls -la | cut -d\  -f4-

Then you'd see the difference.

Even ls -la | awk '{$1=$2=""; print}' which is based on the answer voted best thus far is not preserve the formatting.

Thus I would use the following, and it also allows explicit selective columns in the beginning:

ls -la | cut -d\  -f1,4-

Note that every space counts for columns too, so for instance in the below, columns 1 and 3 are empty, 2 is INFO and 4 is:

$ echo " INFO  2014-10-11 10:16:19  main " | cut -d\  -f1,3

$ echo " INFO  2014-10-11 10:16:19  main " | cut -d\  -f2,4
INFO 2014-10-11
$
查看更多
三岁会撩人
3楼-- · 2019-01-03 01:18

Printing out columns starting from #2 (the output will have no trailing space in the beginning):

ls -l | awk '{sub(/[^ ]+ /, ""); print $0}'
查看更多
做个烂人
4楼-- · 2019-01-03 01:18

Would this work?

awk '{print substr($0,length($1)+1);}' < file

It leaves some whitespace in front though.

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-01-03 01:19

Most solutions with awk leave an space. The options here avoid that problem.

Option 1

A simple cut solution (works only with single delimiters):

command | cut -d' ' -f3-

Option 2

Forcing an awk re-calc sometimes remove the added leading space (OFS) left by removing the first fields (works with some versions of awk):

command | awk '{ $1=$2="";$0=$0;} NF=NF'

Option 3

Printing each field formatted with printf will give more control:

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

However, all previous answers change all repeated FS between fields to OFS. Let's build a couple of option that do not do that.

Option 4 (recommended)

A loop with sub to remove fields and delimiters at the front.
And using the value of FS instead of space (which could be changed).
Is more portable, and doesn't trigger a change of FS to OFS: NOTE: The ^[FS]* is to accept an input with leading spaces.

$ in='    1    2  3     4   5   6 7     8  '
$ echo "$in" | awk '{ n=2; a="^["FS"]*[^"FS"]+["FS"]+";
  for(i=1;i<=n;i++) sub( a , "" , $0 ) } 1 '
3     4   5   6 7     8

Option 5

It is quite possible to build a solution that does not add extra (leading or trailing) whitespace, and preserve existing whitespace(s) using the function gensub from GNU awk, as this:

$ echo '    1    2  3     4   5   6 7     8  ' |
  awk -v n=2 'BEGIN{ a="^["FS"]*"; b="([^"FS"]+["FS"]+)"; c="{"n"}"; }
          { print(gensub(a""b""c,"",1)); }'
3     4   5   6 7     8 

It also may be used to swap a group of fields given a count n:

$ echo '    1    2  3     4   5   6 7     8  ' |
  awk -v n=2 'BEGIN{ a="^["FS"]*"; b="([^"FS"]+["FS"]+)"; c="{"n"}"; }
          {
            d=gensub(a""b""c,"",1);
            e=gensub("^(.*)"d,"\\1",1,$0);
            print("|"d"|","!"e"!");
          }'
|3     4   5   6 7     8  | !    1    2  !

Of course, in such case, the OFS is used to separate both parts of the line, and the trailing white space of the fields is still printed.

NOTE: [FS]* is used to allow leading spaces in the input line.

查看更多
小情绪 Triste *
6楼-- · 2019-01-03 01:19

Perl solution:

perl -lane 'splice @F,0,1; print join " ",@F' file

These command-line options are used:

  • -n loop around every line of the input file, do not automatically print every line

  • -l removes newlines before processing, and adds them back in afterwards

  • -a autosplit mode – split input lines into the @F array. Defaults to splitting on whitespace

  • -e execute the perl code

splice @F,0,1 cleanly removes column 0 from the @F array

join " ",@F joins the elements of the @F array, using a space in-between each element


Python solution:

python -c "import sys;[sys.stdout.write(' '.join(line.split()[1:]) + '\n') for line in sys.stdin]" < file

查看更多
趁早两清
7楼-- · 2019-01-03 01:21

There's a duplicate question with a simpler answer using cut:

 svn status |  grep '\!' | cut -d\  -f2-

-d specifies the delimeter (space), -f specifies the list of columns (all starting with the 2nd)

查看更多
登录 后发表回答