join fields

My input is as below:

1|2|3|a02 test|303
2|2|4|1002 a05 ind|303
4|3|5|ind|30

Output

1|2|3|a02test|303
2|2|4|a05ind|303
4|3|5|ind|30

I used command:

I am getting above output. Is there any simple way using awk to acheive this.
Thanks.

Hi,

I would use next command:

$ cat infile
1|2|3|a02 test|303
2|2|4|1002 a05 ind|303
4|3|5|ind|30
$ awk 'BEGIN { FS = OFS = "|" } { num_words = split( $4, words, /\s+/ ); if ( num_words > 2 ) { sub( /\S+\s/, "", $4 ) } gsub( /\s+/, "", $4 ); print }' infile
1|2|3|a02test|303
2|2|4|a05ind|303
4|3|5|ind|30

Regards,
Birei

kent$  echo "1|2|3|a02 test|303
2|2|4|1002 a05 ind|303
4|3|5|ind|30"|awk -F'|' -v OFS='|' '{$4=gensub(/.* (.*) (.*)$/,"\\1\\2","g",$4);gsub(/ /,"",$4)}1'
1|2|3|a02test|303
2|2|4|a05ind|303
4|3|5|ind|30

An alternative that's both succinct and portable:

awk 'NF==3 {sub(/[^|]*$/, "", $1)} {$0=$1$2$3} 1'

Regards,
Alister

I was thinking about this way too, but it is not safe. e.g.

foo bar|2|3|a02 test|303
2|2 6|4|1002 a05 ind|3 y 03
4|3 x 8|5|ind|30
1 Like

You're absolutely correct.

My only goal was to transform the given sample input into the sample output. Should the actual data deviate in form from what was provided, someone else would have to deal with the carnage. :wink:

Thanks for pointing it out, though. You may have saved someone a little time.

Regards,
Alister

Hi Birai,

I am getting output as same as input.

cat infile
1|2|3|a02 test|303
2|2|4|1002 a05 ind|303
4|3|5|ind|30

awk 'BEGIN { FS = OFS = "|" } { num_words = split( $4, words, /\s+/ ); if ( num_words > 2 ) { sub( /\S+\s/, "", $4 ) } gsub( /\s+/, "", $4 ); print }' infile
1|2|3|a02 tet|303
2|2|4|1002 a05 ind|303
4|3|5|ind|30

Hi SK1418,

Getting error message:

awk -F'|' -v OFS='|' '{$4=gensub(/.* (.*) (.*)$/,"\\1\\2","g",$4);gsub(/ /,"",$4)}1' infile
awk: Function gensub is not defined.
 The input line number is 1. The file is infile.
 The source line number is 1.

i am using HP-UX.