Thursday, January 30, 2014

Awk: Print all but the last field

The other day I had a list of files, and needed to extract a list of the directories containing those files. So, in more general terms, I needed everything but the last field of each line.   That can be done in awk with

awk -F/ '{$NF=""; print $0}' filename 

i.e., you set the Nth field to null, then print the modified item.   You can do that with other fields as well -- $1, $(NF-1), and so on.

But that changes all the slashes to spaces. I knew there were no spaces in my list, so I fixed it with sed:

awk -F/ '{$NF=""; print $0}' filename | sed s/\ /\//g 

I could also have used the OFS (output field separator) directive in awk, but that doesn't work within a one-liner.

awk -F/ 'BEGIN { OFS = "/"}{ $NF=""; print $0 }' filename 

You can also edit the output record separator the same way -- for example, if you're sedawking a batch script, perhaps you want to add semicolons.

awk -F/ 'BEGIN { OFS = "/"; ORS=";\n"}{ $NF=""; print $0 }' filename 

 (h/t One Tip Per Day and GNU)