HollowDev
HollowDev

Reputation: 131

bash - extract specific value from file

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?

Upvotes: 3

Views: 315

Answers (4)

The fourth bird
The fourth bird

Reputation: 163632

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

Upvotes: 2

tshiono
tshiono

Reputation: 22087

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.

Upvotes: 3

boppy
boppy

Reputation: 1908

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)

Upvotes: 5

Thor
Thor

Reputation: 47239

Does your grep support perlregex?

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

Output:

5140

Upvotes: 2

Related Questions