使用grep或awk选择一个字符串

时间:2016-10-18 11:47:59

标签: regex awk grep

我有以下行,我需要获得上面的变量

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

这样:

port=tcp
state=open
name=tor-socks

谢谢

3 个答案:

答案 0 :(得分:1)

这将检查协议,状态,名称和打印等关键字,直到看到第一个空格。 tr用于删除双引号。其中$ x是你的字符串。

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

计算策略-1:

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

同样:

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

计算策略-2:

或只是eval为各个变量赋值。但我会避免这样做,采用第一种方法。

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

答案 1 :(得分:0)

您还可以使用sed从字符串中提取数据,并使用read将单个字符串分配给变量:

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

请注意,变量portstatename的值在{}所包含的块中。

答案 2 :(得分:0)

要满足评论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"

以上使用GNU awk进行多字符RS和RT,我认为你已经对GNU grep解决方案感到满意了。