5

Хорошо, вот быстрый пример; изолировать IPV4 хоста в три этапа:

ip -br a  
lo               UNKNOWN        127.0.0.1/8 ::1/128 
eth0             DOWN           
wlan0            UP             192.168.0.101/24 fe80::9fcd:45fb:1e0f:a1cc/64 
ip -br a | awk '/wlan0/ {print $3}'  
192.168.0.101/24
ip -br a | awk '/wlan0/ {print $3}' | awk -F '/' '{print $1}'
192.168.0.101

Вместо вызова второго экземпляра awk (передача вывода одного в следующий); как это можно сделать за один раз?


Просто хотел сказать: вопрос не в разборе вывода ip . Мне просто нужен был быстрый пример, чтобы проиллюстрировать вопрос; это было первое, что я придумал. Настоящий вопрос обобщен в заголовке.

Во всяком случае, для чего это стоит (мне придется проверить это, но я почти уверен); это то, что я сделал в (недавнем) прошлом:

ip -br a s dev wlan0 | awk -F '[ /]*' '{print $3}'
192.168.0.101

5 ответов5

2

Хотя другие ответы решают основную проблему, на самом деле они не отвечают на вопрос: «Как мне связать операторы awk print?"

Для такого рода проблем ответ таков: «Вы этого не делаете». Вы используете оставшуюся часть языка для манипулирования источником, пока не получите желаемый результат - то, что делают два других ответа. Вы используете только print для вывода окончательного результата.

После того, как вы указали начальный шаблон диапазона, такой как /wlan0/ (или /^wl/ в моем случае, потому что у моего WiFi другое имя), ваше действие, код внутри {} , будет работать только на входных строках, которые содержат эту строку ,

Если у вас есть это, вы можете делать все, что вам нужно, с этой строкой ввода.

ip -br a | \
awk '
/^wl/ {
  ip1 = $3
  gsub(/\/.*/, "", ip1)
  print ip1
}
'

Этот код занимает требуемое поле, помещает его в переменную, редактирует содержимое этой переменной и затем печатает его.

Другой ответ делает то же самое более эффективно, но это иллюстрирует более общий случай, когда могут быть добавлены другие шаги. Вы даже можете сохранить результат для последующего использования с чем-то, найденным в другой строке ввода и т.д.

Для чего-то, что на самом деле может выглядеть больше как "цепочка печати", в awk есть функция sprintf() которая может сделать отформатированную печать своего ввода в переменную для дальнейшей обработки.

Или, если вы печатаете более чем одну вещь в строке, ваш код может использовать несколько операторов printf() без новой строки до последней строки для построения выходной строки по частям.

2

Вы можете использовать gsub для этого как:

ip -br a | awk '/wlan0/ {gsub(/\/.*/, ""); print $3}'
2

Просто измените определение разделителя полей, включив в него пробелы и /:

$ ip -br a | awk -F'[[:blank:]/]+' '/wlan0/{print $3}'
192.168.0.101

Опция -F'[[:blank:]/]+' указывает awk использовать любую комбинацию пробелов, табуляции или косых черт в качестве разделителя полей при вводе.

2

Для этого экземпляра самый простой способ сделать это, вероятно, установить несколько разделителей с помощью регулярного выражения:

ip -br a | awk -F '[\t /]*' '/wlan0/ {print$3}'

Это делает разделитель полей любой строкой / , пробелами или табуляцией, а затем печатает третье поле.

Чтобы выполнить любые две произвольные команды, вам нужно выучить полный язык программирования awk. Я бы рекомендовал против этого - я уверен, что у вас есть дела поважнее.

0

Это несколько в духе ответа Стивена Рауха и ответа Джо, но лучше:

awk '/wlan0/ {split($3, a, "/"); print a[1]}'

Это займет третье поле ($3) и split его, используя / в качестве разделителя.  Компоненты входят в массив a , и возвращается число подполей.  (В этом фрагменте я игнорирую возвращаемое значение.)  Таким образом, a[1] является первым / -ограниченным подполем третьего поля.

Это легче обобщить, чем другие ответы.  Например, если ваш ввод

Once upon a midnight dreary, while I pondered, weak and weary,
Over many a quaint and curious volume of forgotten lore—
wlan0 foo/bar the/quick/brown/fox/jumps/over/the lazy/dog
While I nodded, nearly napping, suddenly there came a tapping,
As of some one gently rapping—rapping at my chamber door.

тогда команда

awk '/wlan0/ {if (split($3, a, "/") < 4) print "There is no fourth subfield";
                                    else print "The fourth subfield is", a[4]}'

напечатает четвертое подполе третьего поля третьей строки (fox), после проверки возвращаемого значения из split чтобы убедиться, что есть (по крайней мере) четыре подполя.  То есть это как

awk '/wlan0/ {print $3}' | awk -F '/' '{print $4}'

в одной команде awk , с проверкой ошибок.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .