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:30

I wasn't happy with any of the awk solutions presented here because I wanted to extract the first few columns and then print the rest, so I turned to perl instead. The following code extracts the first two columns, and displays the rest as is:

echo -e "a  b  c  d\te\t\tf g" | \
  perl -ne 'my @f = split /\s+/, $_, 3; printf "first: %s second: %s rest: %s", @f;'

The advantage compared to the perl solution from Chris Koknat is that really only the first n elements are split off from the input string; the rest of the string isn't split at all and therefor stays completely intact. My example demonstrates this with a mix of spaces and tabs.

To change the amount of columns that should be extracted, replace the 3 in the example with n+1.

查看更多
Explosion°爆炸
3楼-- · 2019-01-03 01:31

will print all but very first column:

awk '{$1=""; print $0}' somefile

will print all but two first columns:

awk '{$1=$2=""; print $0}' somefile
查看更多
【Aperson】
4楼-- · 2019-01-03 01:33

If you don't want to reformat the part of the line that you don't chop off, the best solution I can think of is written in my answer in:

How to print all the columns after a particular number using awk?

It chops what is before the given field number N, and prints all the rest of the line, including field number N and maintaining the original spacing (it does not reformat). It doesn't mater if the string of the field appears also somewhere else in the line.

Define a function:

fromField () { 
awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}

And use it like this:

$ echo "  bat   bi       iru   lau bost   " | fromField 3
iru   lau bost   
$ echo "  bat   bi       iru   lau bost   " | fromField 2
bi       iru   lau bost 

Output maintains everything, including trailing spaces

In you particular case:

svn status | grep '\!' | fromField 2 > removedProjs

If your file/stream does not contain new-line characters in the middle of the lines (you could be using a different Record Separator), you can use:

awk -v m="\x0a" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'

The first case will fail only in files/streams that contain the rare hexadecimal char number 1

查看更多
疯言疯语
5楼-- · 2019-01-03 01:33

Awk examples looks complex here, here is simple Bash shell syntax:

command | while read -a cols; do echo ${cols[@]:1}; done

Where 1 is your nth column counting from 0.


Example

Given this content of file (in.txt):

c1
c1 c2
c1 c2 c3
c1 c2 c3 c4
c1 c2 c3 c4 c5

here is the output:

$ while read -a cols; do echo ${cols[@]:1}; done < in.txt 

c2
c2 c3
c2 c3 c4
c2 c3 c4 c5
查看更多
SAY GOODBYE
6楼-- · 2019-01-03 01:33

Because of a wrong most upvoted anwser with 340 votes, I just lost 5 minutes of my life! Did anybody try this answer out before upvoting this? Apparantly not. Completely useless.

I have a log where after $5 with an IP address can be more text or no text. I need everything from the IP address to the end of the line should there be anything after $5. In my case, this is actualy withn an awk program, not an awk oneliner so awk must solve the problem. When I try to remove the first 4 fields using the most upvoted but completely wrong answer:

echo "  7 27.10.16. Thu 11:57:18 37.244.182.218" | awk '{$1=$2=$3=$4=""; printf "[%s]\n", $0}'

it spits out wrong and useless response (I added [..] to demonstrate):

[    37.244.182.218 one two three]

There are even some sugestions to combine substr with this wrong answer. Like that complication is an improvement.

Instead, if columns are fixed width until the cut point and awk is needed, the correct answer is:

echo "  7 27.10.16. Thu 11:57:18 37.244.182.218" | awk '{printf "[%s]\n", substr($0,28)}'

which produces the desired output:

[37.244.182.218 one two three]
查看更多
爷的心禁止访问
7楼-- · 2019-01-03 01:34

This would work if you are using Bash and you could use as many 'x ' as elements you wish to discard and it ignores multiple spaces if they are not escaped.

while read x b; do echo "$b"; done < filename
查看更多
登录 后发表回答