How about adding dummy interface and setting the route to that interface?
# ip link add dummy0 type dummy
# ip link set dev dummy0 up
# ip route add 8.8.8.8/32 dev dummy0
# ping -c3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2015ms
It always sends packets for any (neighbor or remote) addresses on dummy0
.
# tshark -i dummy0
Running as user "root" and group "root". This could be dangerous.
Capturing on 'dummy0'
1 0.000000 10.10.0.59 -> 8.8.8.8 ICMP 98 Echo (ping) request id=0x1ce0, seq=1/256, ttl=64
2 1.007348 10.10.0.59 -> 8.8.8.8 ICMP 98 Echo (ping) request id=0x1ce0, seq=2/512, ttl=64
3 2.015394 10.10.0.59 -> 8.8.8.8 ICMP 98 Echo (ping) request id=0x1ce0, seq=3/768, ttl=64
Если у вас есть GNU grep, вы можете написать
grep -oP '\binternal_num\s*=\s*\K\d+' file.xml
Но вам не следует анализировать XML с помощью регулярных выражений. Возможно, вам нужно что-то вроде этого
$ echo '
<root>
<tag>
<tag>
<wanted internal_num="1234" />
<wanted internal_num = "5678" />
</tag>
</tag>
</root>
' | xmlstarlet sel -t -v '//@internal_num' -n
1234
5678
Пожалуйста, покажите исходный файл.
Вы используете расширенное регулярное выражение, но по-прежнему экранируете \+
, поэтому оно ищет буквальный знак плюс и не вызывает подстановку.
Попробуйте,
INTERNAL_NUM=$(grep -E '\s*internal_num\s*=' file.xml |sed -E 's/internal_num\s*=\s*([0-9]+)/\1/')
echo "$INTERNAL_NUM"
Тестовые наборы (протестированы на GNU sed V4.2.1):
$ echo "internal_num = 1234" | sed -E 's/internal_num\s*=\s*([0-9]\+)/\1/'
internal_num = 1234
$ echo "internal_num = 1234" | sed -E 's/internal_num\s*=\s*([0-9]+)/\1/'
1234
Поскольку в других ответах упоминается (и подробно объясняется ), вам следует серьезно подумать о том, чтобы не использовать регулярное выражение для анализа XML.
Различные инструменты и реализации/версии данного инструмента поддерживают разный синтаксис регулярных выражений.
Для переносимости вы можете ограничиться набором функций POSIX:
s=[[:space:]]
sed -n "s/^\(.*$s\)\{0,1\}internal_num$s*=$s*\([0-9]\{1,\}\).*/\2/p"
(при условии, что в строке есть только одно вхождение)
Если вы знаете, что будете запускать его только на системах, где grep
поддерживает -o
и-P
(для Perl -например, регулярные выражения )а-ля GNU grep
, вы можете сделать:
grep -Po '(?<!\S)internal_num\s*=\s*\K\d+'