2

say i have a file

#cat file.log
abc|123|text1 modesc=bpp123 raw_info=clear
abc|123|text2 modesc=pmk123 severity=minor
abc|123|text3 modesc=pnj123 info=good

only want to know what words in print $3 appear after "modesc=" untill space,

I would much prefer that the output of that command looked like this:

abc|123|bpp123
abc|123|pmk123
abc|123|pnj123

Using bash, I would like to just print out where $3 just get the word after "modesc=". Is there a way to do this?

1
$ sed 's/[^|]*modesc=\([^ ]*\).*$/\1/' file
abc|123|bpp123
abc|123|pmk123
abc|123|pnj123

This uses sed to replace the whole last field with the contents after modesc= up to the next space.


$ awk -F '|' -vOFS='|' '{ sub(".*modesc=", "", $3); sub(" .*", "", $3)} 1' file
abc|123|bpp123
abc|123|pmk123
abc|123|pnj123

This awk program modifies the third column with two substitutions. The first removes everything up to and including modesc=, and the second one removes everything after the first remaining space. The lone 1 at the end will cause awk to print the modified record (this may be replaced by { print }).


To only get the string after modesc= from the third column of the original data (and not anything else), you may use either of the above commands and then pipe that through cut -d '|' -f3, or you may use

sed 's/.*modesc=\([^ ]*\).*$/\1/' file

or

awk -F '|' -vOFS='|' '{ sub(".*modesc=", "", $3); sub(" .*", "", $3); print $3 }' file
1

With awk you can use multiply delimiters and do it quite sample:

awk -F'[|= ]' ' {print $1"|" $2"|" $5}' /tmp/file.log

In above line pipe |, equiv sign = and space are delimiters.

You can define output delimiter explicitly like this:

awk -F'[|= ]' 'BEGIN { OFS="|"}  {print $1,$2,$5}' /tmp/file.log
  • 1
    The print $1 $2 $5 need the commas for the OFS to take effect. Right now they'll be just concatenated. – Rakesh Sharma Jun 4 '18 at 9:06
  • @RakeshSharma, right, will correct it :) – Romeo Ninov Jun 4 '18 at 9:12
  • 1
    Nice solution. The assumption is that the order of the words in field 3 do not change. – glenn jackman Jun 4 '18 at 11:07
  • Right. If the case is not this I expect OP will enter it in to the example input :) – Romeo Ninov Jun 4 '18 at 11:40
0

Using awk:

awk -F\| '{print $1"|"$2"|"gensub(/modesc=(.*) .*$/,"\\1","g",$3)}' /tmp/file.log
0

This will be less efficient, but the task fits nicely with cut and paste

paste -d '|' <(cut -d'|' -f1-2 file.log) <(cut -d'|' -f3 file.log | grep -oP 'modesc=\K\S+')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.