#regex #awk #grep
#регулярное выражение #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
Спасибо
Комментарии:
1. Вы хотите
port=tcp
илиprotocol=tcp
?
Ответ №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. Спасибо! и у меня есть еще один вопрос. мне нужно получить это в переменной типа $ echo «$protocol», а вывод — «tcp»
2. Спасибо! впервые я вижу практическое использование eval 🙂
3. @JackMagor вы можете принять ответ, отметив его, если это поможет
4. Не делайте этого. Нет абсолютно никаких причин использовать eval для этого, и все обычные причины этого не делают. Также обратите внимание на все переменные без кавычек, которые также являются основным красным флажком.
Ответ №2:
Чтобы удовлетворить требование из вашего комментария, что 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.
Ответ №3:
Вы также можете использовать sed
для извлечения ваших данных из строки и назначения read
отдельной строки переменным :
echo $line | sed 's/.*protocol="([^"]*)".*state="([^"]*)".*name="([^"]*)".*/1 2 3/' | { read port state name; echo $port $state $name; }
Обратите внимание, что переменные port
, state
, name
имеют свое значение внутри блока, заключенного в {
и }
.