Jam
Jam

Reputation: 129

Select a string using grep or awk

i have the follow line and i need to get the variables like above

<port protocol="tcp" portid="9050"><state state="open" reason="syn-ack" reason_ttl="64"/><service name="tor-socks" method="table" conf="3"/></port>

this:

port=tcp
state=open
name=tor-socks

thank you

Upvotes: 0

Views: 85

Answers (3)

Ed Morton
Ed Morton

Reputation: 203522

To satisfy the requirement from your comment that i need to get this in variable like $ echo "$protocol" and output is "tcp":

$ cat tst.sh
declare $(awk -v RS='[[:alpha:]]+="[^"]+"' 'RT{print RT}' "$1")
echo "$protocol"
echo "$state"
echo "$name"

$ ./tst.sh file
"tcp"
"open"
"tor-socks"

The above uses GNU awk for multi-char RS and RT which I assume you have since you were happy with a GNU grep solution.

Upvotes: 0

oliv
oliv

Reputation: 13249

You can also use sed to extract your data from the string and use read to assign individual string to variables :

 echo $line | sed 's/.*protocol="\([^"]*\)".*state="\([^"]*\)".*name="\([^"]*\)".*/\1 \2 \3/' | { read port state name; echo $port $state $name; }

Note that the variables port, state, name have their value inside the block enclosed by { and }.

Upvotes: 0

P....
P....

Reputation: 18371

This will check for keywords like protocol,state,name and print till first space is seen. tr is used to remove double quotes. Where $x is your string.

echo $x  |grep -oP 'protocol=.*? |state=.*? |name=.*? ' |tr -d '"'
protocol=tcp
state=open
name=tor-socks

Approch-1:

protocol=$( echo $x  |grep -oP '(?<=protocol=").*?(?=")')
echo $protocol
tcp

Similarly :

protocol=$( echo $x  |grep -oP '(?<=protocol=").*?(?=")')
state=$(echo $x  |grep -oP '(?<=state=").*?(?=")')
name=$(echo $x  |grep -oP '(?<=name=").*?(?=")')

Approch-2:

or just do eval to assign values to respective variables. But I would avoid doing this, go with the first approach.

eval $(echo $x  |grep -oP 'protocol=.*? |state=.*? |name=.*? ')
echo $state
open

Upvotes: 1

Related Questions