Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Print rest of the fields in awk

Tags:

bash

awk

Suppose we have this data file.

john 32 maketing executive jack 41 chief technical officer jim  27 developer dela 33 assistant risk management officer 

I want to print using awk

john maketing executive jack chief technical officer jim  developer dela assistant risk management officer 

I know it can be done using for.

awk '{printf $1;  for(i=3;i<=NF;i++){printf " %s", $i} printf "\n"}' < file 

Problem is its long and looks complex.

Is there any other short way to print rest of the fields.

like image 813
Shiplu Mokaddim Avatar asked Aug 27 '13 05:08

Shiplu Mokaddim


People also ask

How do I print all columns in awk?

With space as the separator you could even generalize the solution; e.g., the following returns everything from the 3rd field: awk '{sub(/^[ ]*([^ ]+ +){2}/, ""); print $0}' It gets trickier with arbitrary field separators, though.

How do I print awk space?

To place the space between the arguments, just add " " , e.g. awk {'print $5" "$1'} . However it is not recommended to parse output of ls command, since it's not reliable and output is for humans, not scripts. Therefore use alternative commands such as find or stat .

Can I use cut with awk?

You can cut in awk using awk's function split . You can also filter records using a regex condition within awk, making grep and cut superfluous.


2 Answers

Set the field(s) you want to skip to blank:

awk '{$2 = ""; print $0;}' < file_name 

Source: Using awk to print all columns from the nth to the last

like image 64
Barun Avatar answered Sep 17 '22 09:09

Barun


Reliably with GNU awk for gensub() when using the default FS:

$ gawk -v delNr=2 '{$0=gensub("^([[:space:]]*([^[:space:]]+[[:space:]]+){"delNr-1"})[^[:space:]]+[[:space:]]*","\\1","")}1' file john maketing executive jack chief technical officer jim  developer dela assistant risk management officer 

With other awks, you need to use match() and substr() instead of gensub(). Note that the variable delNr above tells awk which field you want to delete:

$ gawk -v delNr=3 '{$0=gensub("^([[:space:]]*([^[:space:]]+[[:space:]]+){"delNr-1"})[^[:space:]]+[[:space:]]*","\\1","")}1' file john 32 executive jack 41 technical officer jim  27 dela 33 risk management officer 

Do not do this:

awk '{sub($2 OFS, "")}1' 

as the same text that's in $2 might be at the end of $1, and/or $2 might contain RE metacharacters so there's a very good chance that you'll remove the wrong string that way.

Do not do this:

awk '{$2=""}1' file 

as it adds an FS and will compress all other contiguous white space between fields into a single blank char each.

Do not do this:

awk '{$2="";sub("  "," ")}1' file 

as it hasthe space-compression issue mentioned above and relies on a hard-coded FS of a single blank (the default, though, so maybe not so bad) but more importantly if there were spaces before $1 it would remove one of those instead of the space it's adding between $1 and $2.

One last thing worth mentioning is that in recent versions of gawk there is a new function named patsplit() which works like split() BUT in addition to creating an array of the fields, it also creates an array of the spaces between the fields. What that means is that you can manipulate fields and the spaces between then within the arrays so you don't have to worry about awk recompiling the record using OFS if you manipulate a field. Then you just have to print the fields you want from the arrays. See patsplit() in http://www.gnu.org/software/gawk/manual/gawk.html#String-Functions for more info.

like image 38
Ed Morton Avatar answered Sep 17 '22 09:09

Ed Morton