Использование awk в Linux
Текст это сердце Unix. Философия «все есть файл» полностью пронизывает всю систему и разработанные для нее инструменты. Вот почему работа с текстом является одним из обязательных навыков не только системного администратора, но и обычного пользователя Linux, который хочет поглубже разобраться в этой операционной системе.
Команда awk — один из самых мощных инструментов для обработки и фильтрации текста, доступный даже для людей никак не связных с программированием. Это не просто утилита, а целый язык разработанный для обработки и извлечения данных. В этой статье мы разберемся как пользоваться awk.
Синтаксис команды awk
Сначала надо понять как работает утилита. Она читает документ по одной строке за раз, выполняет указанные вами действия и выводит результат на стандартный вывод. Одна из самых частых задач, для которых используется awk — это выборка одной из колонок. Все параметры awk находятся в кавычках, а действие, которое надо выполнить — в фигурных скобках. Вот основной её синтаксис:
$ awk опции ‘ условие < действие >‘
$ awk опции ‘ условие < действие >условие < действие >‘
С помощью действия можно выполнять преобразования с обрабатываемой строкой. Об этом мы поговорим позже, а сейчас давайте рассмотрим опции утилиты:
- -F, —field-separator — разделитель полей, используется для разбиения текста на колонки;
- -f, —file — прочитать данные не из стандартного вывода, а из файла;
- -v, —assign — присвоить значение переменной, например foo=bar;
- -b, —characters-as-bytes — считать все символы однобайтовыми;
- -d, —dump-variables — вывести значения всех переменных awk по умолчанию;
- -D, —debug — режим отладки, позволяет вводить команды интерактивно с клавиатуры;
- -e, —source — выполнить указанный код на языке awk;
- -o, —pretty-print — вывести результат работы программы в файл;
- -V, —version — вывести версию утилиты.
Это далеко не все опции awk, однако их вам будет достаточно на первое время. Теперь перечислим несколько функций-действий , которые вы можете использовать:
- print(строка) — вывод чего либо в стандартный поток вывода;
- printf(строка) — форматированный вывод в стандартный поток вывода;
- system(команда) — выполняет команду в системе;
- length(строка) — возвращает длину строки;
- substr(строка, старт, количество) — обрезает строку и возвращает результат;
- tolower(строка) — переводит строку в нижний регистр;
- toupper(строка) — переводить строку в верхний регистр.
Функций намного больше, но чтобы не загромождать статью я привел только те, которые мы будем использовать сегодня, а также ещё несколько для чтобы вы могли оценить масштаб возможностей утилиты.
В функциях-действиях можно использовать различные переменные и операторы, вот несколько из них:
- FNR — номер обрабатываемой строки в файле;
- FS — разделитель полей;
- NF — количество колонок в данной строке;
- NR — общее количество строк в обрабатываемом тексте;
- RS — разделитель строк, по умолчанию символ новой строки;
- $ — ссылка на колонку по номеру.
Кроме этих переменных, есть и другие, а также можно объявлять свои.
Условие позволяет обрабатывать только те строки, в которых содержатся нужные нам данные, его можно использовать в качестве фильтра, как grep. А ещё условие позволяет выполнять определенные блоки кода awk для начала и конца файла, для этого вместо регулярного выражения используйте директивы BEGIN (начало) и END (конец). Там ещё есть очень много всего, но на сегодня пожалуй достаточно. Теперь давайте перейдем к примерам.
Использование awk в Linux
Простейшая и часто востребованная задача — выборка полей из стандартного вывода. Вы не найдете более подходящего инструмента для решения этой задачи, чем awk. По умолчанию awk разделяет поля пробелами. Если вы хотите напечатать первое поле, вам нужно просто использовать функцию print и передать ей параметр $1, если функция одна, то скобки можно опустить:
echo ‘one two three four’ | awk »
Да, использование фигурных скобок немного непривычно, но это только в первое время. Вы уже догадались как напечатать второе, третье, четвертое, или другие поля? Правильно это $2, $3, $4 соответственно.
echo ‘one two three four’ | awk »
Иногда необходимо представить данные в определенном формате, например, выбрать несколько слов. AWK легко справляется с группировкой нескольких полей и даже позволяет включать статические данные:
echo ‘one two three four’ | awk »
Если поля разделены не пробелами, а другим разделителем, просто укажите в параметре -F нужный разделитель в кавычках, например «:» :
echo ‘one mississippi:two mississippi:three mississippi:four mississippi’ | awk -F»:» »
Но разделитель не обязательно заключать в кавычки. Следующий вывод аналогичен предыдущему:
echo ‘one mississippi:two mississippi:three mississippi:four mississippi’ | awk -F: »
Иногда нужно обработать данные с неизвестным количеством полей. Если вам нужно выбрать последнее поле можно воспользоваться переменной $NF. Вот так вы можете вывести последнее поле:
echo ‘one two three four’ | awk »
Также вы можете использовать переменную $NF для получения предпоследнего поля:
echo ‘one two three four’ | awk »
echo ‘one two three four five’ | awk »
Все это можно сделать с помощью таких утилит как sed, cut и grep но это будет намного сложнее.
Как я рассказывал выше, awk обрабатывает одну строку за раз, вот этому подтверждение:
А вот пример фильтрации с помощью условия, выведем только строку, в которой содержится текст one:
echo -e ‘one 1\n two 2’ | awk ‘/one/ ‘
А вот пример использования операций с переменными:
echo -e ‘one 1\n two 2’ | awk ‘ END ‘
Это означает что мы должны выполнять следующий блок кода для каждой строки. Это можно использовать, например, для подсчета количества переданных данных по запросам из журнала веб-сервера.
Представьте себе, у нас есть журнал доступа, который выглядит так:
Мы можем подсчитать, что количество переданных байт, это десятое поле. Дальше идёт User-Agent пользователя и он нам не интересен:
cat /var/log/apache2/access.log | awk »
Вот так можно подсчитать количество байт:
Это только несколько примеров показывающих использование awk в Linux , освоив awk один раз в получите очень мощный и полезный инструмент на всю жизнь.
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.
Как вывести от определённого столбца до последнего в командной строке Linux
В этой заметке рассмотрим, как вывести с определённого столбца до последнего. Например:
- как вывести со второго столбца до последнего
- как вывести с третьего столбца до последнего
- как вывести с четвёртого столбца до последнего
- как вывести с n-го столбца до последнего
- как вывести последний столбец
Чтобы вывести с определённой колонки до самой последней наиболее удобна команда cut. Если по каким-либо причинами вы предпочитаете команду awk, то здесь будут показаны примера вывода с определённого столбца до последнего с помощью команды awk.
cut
Как вывести с n-го столбца до последнего:
Используйте следующую команду, в которой «N» замените на номер колонки, с которой необходимо начать вывод:
Как вывести со второго столбца до последнего:
echo 'vddp vddpi vss cb0 cb1 cb2 cb3 ct0 ct1 ct2 ct3' | cut -f2- -d' '
Как вывести с третьего столбца до последнего:
echo 'vddp vddpi vss cb0 cb1 cb2 cb3 ct0 ct1 ct2 ct3' | cut -f3- -d' '
Как вывести с четвёртого столбца до последнего:
echo 'vddp vddpi vss cb0 cb1 cb2 cb3 ct0 ct1 ct2 ct3' | cut -f4- -d' '
awk
Как вывести с n-го столбца до последнего:
В awk вы можете использовать конструкцию вида:
Этот пример очистит содержимое первых трёх столбцов и покажет все колонки, начиная с четвёртого столбца.
Но при этом пробелы, который находятся между первым и вторым столбцом, вторым и третьим столбцом, а также третьим и четвёртым столбцом удалены не будут и будут показаны. Чтобы их удалить используйте дополнительно команду sed:
Либо вы можете использовать следующую команду awk которая очищает пробелы между удалёнными стобцами:
Смотрите также: Уроки по Awk
Как вывести со второго столбца до последнего:
echo 'vddp vddpi vss cb0 cb1 cb2 cb3 ct0 ct1 ct2 ct3' | awk '' | sed -r "s/^\s+//g" echo 'vddp vddpi vss cb0 cb1 cb2 cb3 ct0 ct1 ct2 ct3' | awk ''
Как вывести с третьего столбца до последнего:
echo 'vddp vddpi vss cb0 cb1 cb2 cb3 ct0 ct1 ct2 ct3' | awk '' | sed -r "s/^\s+//g" echo 'vddp vddpi vss cb0 cb1 cb2 cb3 ct0 ct1 ct2 ct3' | awk ''
Как вывести с четвёртого столбца до последнего:
echo 'vddp vddpi vss cb0 cb1 cb2 cb3 ct0 ct1 ct2 ct3' | awk '' | sed -r "s/^\s+//g" echo 'vddp vddpi vss cb0 cb1 cb2 cb3 ct0 ct1 ct2 ct3' | awk ''
Как вывести последний столбец
Для вывода последнего столбца с помощью awk используйте команду:
echo 'vddp vddpi vss cb0 cb1 cb2 cb3 ct0 ct1 ct2 ct3' | awk ''
Смотрите также: Уроки по Awk
Если вы хотите обойтись без awk, то используйте следующий набор команд:
echo 'vddp vddpi vss cb0 cb1 cb2 cb3 ct0 ct1 ct2 ct3' | rev | cut -d' ' -f1 | rev
Связанные статьи:
Вывод нужных столбцов в консоле
Ребят подскажите, не могу сделать простое действие. Есть команда вывода всех контейнеров docker ps -a, но все колонки мне не нужны, да они и не умещаются на экран. А вот как вывести только нужные колонки? Вроде есть команды cut и awk. Но нижние колонки ломаются. К примеру docker ps -a | awk выводит нужные колонки, но внизу вся информация ломается, выводится какая то ахинея. Может кто подскажет?
Для справки по кейвордам читай ps(1).
Интересно было бы понять сам механизм, как можно выделить из большой таблицы только нужные столбцы. Это может в куча мест пригодиться. А вывод docker контейнеров это пример, на котором я тренируюсь. По сути awk работает, но только для первой строки. Остальные строки как то перемешиваются. И там выводится абы что.
andy03 ★ ( 07.07.20 14:54:20 MSK )
Последнее исправление: andy03 07.07.20 15:07:20 MSK (всего исправлений: 1)
Ещё раз повторяю: вывод ps не является таблицей! Это обычные строки.
По сути awk работает, но только для первой строки. Остальные строки как то перемешиваются.
Из-за разного количества слов в строке, из-за отсутствия форматирования (для awk любое количество пробелов, если не указано иного опцией -F , является разделителем ввода, вывод значений, разделённых запятой, разделяется одним пробелом).
one two three four five # для awk здесь 5 "столбцов" one two three five # для awk здесь 4 "столбца" one two four # для awk здесь 3 "столбца" one two four six # для awk здесь 4 "столбца"
Если в твоей ОС ps умеет в libxo, ты можешь формировать вывод в json и парсить его чем-нибудь типа jq (или библиотекой на любом удобном для тебя скриптовом языке вроде Python).
Остальные строки как то перемешиваются. И там выводится абы что.
Ты хочешь вывести красиво нужные тебе столбцы в терминал? Если да, то ещё раз почитай man ps , в частности про опцию -o и её аргументы.
Если ты хочешь заскриптовать, то в первую очередь смотри в сторону libxo, если нет, то поиграйся с последовательностью выводимых данных, чтобы вывод не колбасило.
Большое спасибо за развёрнутый ответ! Теперь всё стало гораздо понятнее. Это то что нужно.