Назад | Перейти на главную страницу

Можно ли вместо этого использовать awk?

Я хочу получить номер от rating как результат этого

# nc localhost 9571 
language:
language:en_ZA.UTF-8
language:en_ZW.UTF-8
session-with-name:Ubuntu Classic (No effects):gnome-session --session=2d-gnome
session-with-name:Ubuntu (Safe Mode):gnome-session -f --session=2d-gnome
session-with-name:Ubuntu Classic:gnome-session --session=classic-gnome
xsession:/etc/X11/Xsession
rating:94

Я могу сделать это вот так

# nc localhost 9571 | grep rating | cut -d: -f2
94

но мог awk использоваться вместо этого для более простого решения?

$ nc localhost 9571 | awk -F: '/rating/ { print $2 }'

Quanta меня опередила, но я добавлю sed вариант, если вы так склонны:

nc localhost 9571 | sed -ne 's/^rating://p'

Впрочем, то же самое, что сказал MadHatter. Ваше текущее решение идеально подходит. (Хотя я бы искал "^rating:" а не просто слово, чтобы получить только нужную строку.)

Вы также можете просто использовать оболочку:

nc localhost 9571 | 
while IFS=: read key val; do [[ $key = "rating" ]] && echo "$val"; done

да, вы можете (и должны) использовать (один) awk вместо (двух) grep и cut:

$ nc localhost 9571 | awk -F: '/^rating:/ { print $2 }'

Убедитесь, что вы подобрали линию как можно лучше, чтобы избежать уродливых ошибок.

  • /rating/ работает,
  • /^rating/ лучше (безопаснее),
  • /^rating:/ лучше всего (в данном случае).

Это может:

nc localhost 9571  | awk -F: '{ if ($1 == "rating") print $2 }' 

(Я не знаю, что вы делаете с localhost выше, поэтому использовал ваш вывод в качестве входных данных для моей команды awk, а затем заменил «cat» на «nc ...» - но все должно быть в порядке.)

Но зачем вам это делать? Путь UNIX состоит в том, чтобы иметь множество небольших инструментов, каждый из которых хорошо выполняет одну задачу, связанных конвейерами, вместо использования более крупных многофункциональных инструментов. Вам нужно выбрать одну совпадающую строку, а затем выбрать одно поле: grep выбирает строки с совпадениями, и cut выбирает поля из строк ввода; они идеально подходят для этой задачи. Но если вы действительно хотите сделать это все в одном с awk, что ж, готово.

Хотя квантовый ответ самый простой, и я бы тоже его написал, держу пари, вы не знали GNU awk (gawk) тоже может работать в сети? Вы можете написать все это с помощью awk, если действительно хотите:

BEGIN {
    FS = ":"
    f = "/inet/tcp/0/127.0.0.1/9571"
    while ((f |& getline) > 0)
        if ($1 ~ /^rating$/) {print $2}
}

Это может быть полезно, если на сервере не установлен nc, nc имеет ограниченные perms или вам просто нравится awk.

Вы также можете использовать sed,

nc localhost 9571 | sed -n "s/^rating:\([\d]*\)/\1/p"

Это гарантирует, что "рейтинг" начинается в строке, а цифры следуют за rating:

Если Perl - вариант:

nc localhost 9571 | perl -F: -lane 'print $F[1] if /rating/'

-a автоматически разбивает каждую строку на @F массив
-F: использует : в качестве разделителя полей вместо пробелов по умолчанию
/rating/ возвращает истину, если регулярное выражение найдено
$F[1] это 2-й элемент @F массив.
Массивы Perl начинаются с элемента 0, тогда как awk начинается с $ 1