Home > Blockchain >  Combine multiple fields with awk
Combine multiple fields with awk

Time:10-19

I want to get abc/123/efg from abc/123/efg/456

I try to get the first NF - 1 fields and concatenate them with /.

So I do:

echo abc/123/efg/456 | awk -F "/" 'BEGIN {OFS="/"} {for(i=1;i<=NF-1;i  ) {var = var $i} END {print var}'

However, it did not work as I expected.

What am I doing wrong?

Is there any way to do this more elegantly?

CodePudding user response:

To fix your code:

echo "abc/123/efg/456" | awk -F "/" 'BEGIN {OFS="/"} {
  for(i=1;i<NF;i  ) var = (var ? var OFS : "") $i
}
END {print var}'

As an alternative, you might for example remove starting from the last occurrence of / until the end of the string.

echo "abc/123/efg/456" | awk '{sub("/[^/]*$", "")}1'

Output

abc/123/efg

CodePudding user response:

One idea would be to decrement NF, eg:

$ echo 'abc/123/efg/456' | awk 'BEGIN {FS=OFS="/"} NF--'
abc/123/efg

Whether or not this is the 'best' solution is going to depend on the rest of your coding requirements, ie:

  • if you're doing additional work within awk then this could be combined with other awk scripting
  • if the only purpose of awk is to strip off the last field then this may be overkill and a better (?) solution may be to perform the operation in bash (eg, parameter substitution, dirname, etc)

CodePudding user response:

Here is my approach: Remove the last field. Yes, it is that easy. The code:

echo "abc/123/efg/456" | awk -F/ -vOFS=/ '{NF--; print}'

Notes

  • The flag -F/ specifies the input field separator
  • The flag -vOFS=/ specifies the output field separator
  • The NF-- statement decreases the number of fields by one
  • The print statement prints the whole record (line) after the removal of the last field

CodePudding user response:

simplest approach (if you're concerned with extra blank lines)

echo 'abc/123/efg/456\n\n' |
 nawk 'NF=(-_<NF) * 3' FS='[/]' OFS='/'    
 mawk 'NF * (NF = 3)' FS='[/]' OFS='/'
abc/123/efg

if you're concerned about decrementing NF all the way to negative zone :

mawk2 'NF -= !!NF' FS='[/]' OFS='/'

or just have FS OFS scrub it for u, risk free :

 gawk NF=NF FS='[/][^/]*$' OFS=

if those represent nested folders/directories of any kind, then use this trick to get a 2D tree view :

 nawk 'NF-=!!NF' FS='[/]' OFS='\f\b/'
abc
  /123
     /efg
  • Related