Home > Software engineering >  bash - extract specific value from file
bash - extract specific value from file

Time:08-17

I have a file that looks like this:

odule(load="imfile" PollingInterval="10")
$MaxMessageSize 65536
#RSYSLOG_ForwardFormat template is used to enable millisecond-accuracy
$ActionForwardDefaultTemplate RSYSLOG_ForwardFormat
module(load="imudp")
input(type="imudp" port="5140")

mail.info stop

# This is rule for filtering apache logs
:msg, regex, ".*DHCP.*" stop
:msg, regex, ".*HTTP/1.1\" 200 [0-9-]* \"-\" \"ClusterListener/1.0\".*" stop

global(
  workDirectory="/var/lib/rsyslog"   # Directory where queue files will be stored
)

I want to extract the value of port (which is 5140) and store it in an environment variable.

I have tried using variations of awk, grep, and cat commands to try and achieve this but none seem to give me the desired output.

For example, sed -n 's/port=\(.*\)/\1/p' < file.conf gives the following:

input(type="imudp" "5140")

Which is not what I want. I simply want to store 5140 into an environment variable.

Can anyone help with this?

CodePudding user response:

Since you tagged it, and we already have a sed and a grep way, here's the awk way ;)

awk -F'[ "]' '/port=/{ print $5 }' file.conf

Or to have it in a variable myvar:

myvar=$(awk -F'[ "]' '/port=/{ print $5 }' file.conf)

CodePudding user response:

Would you please try the following:

export port=$(sed -nE 's/.*port="([^"] )".*/\1/p' file.txt)

then the environment variable port will be assigned to 5140.

CodePudding user response:

Does your grep support perlregex?

grep -oP '^input\(.*port="\K\d ' infile

Output:

5140

CodePudding user response:

You are capturing and not matching the " before and after port= so they will be there after replacing.

If you want to get the capture group value only, you have to match all before and after the group value to not have it in the replacement.

If the port can only be 1 or more digits, you can make it a bit more specific [[:digit:]]\

sed -n 's/.*port="\([[:digit:]]\ \)".*/\1/p' < file.conf

Output

5140

If you want to make it a bit more specific:

sed -n 's/^input([^()]*port="\([[:digit:]]\ \)").*/\1/p' < file.conf

The pattern matches

  • ^input( match input( at the start of the string
  • [^()]* Optionally match any character except ( or )
  • port=" Match literally
  • \([[:digit:]]\ \) Capture 1 digits in group 1
  • ") Match ")
  • .* Match the rest of the line
  • Related