
В этом базовом руководстве вы узнаете самые основы команды
awk, а также увидите некоторые способы её использования при работе с текстом, включая вывод содержимого файла, а также его конкретных столбцов, строк и слов по указанным критериям. Приступим!Что это за команда awk?
AWK – это скриптовый язык, который полезен при работе в командной строке и широко применяется для обработки текста.
При использовании
awk вы можете выбирать данные – один или более отдельных фрагментов текста – на основе заданного критерия. Например, с помощью awk можно выполнять поиск конкретного слова или шаблона во фрагменте текста, а также выбирать определённую строку/столбец в файле. Базовый синтаксис awk
Простейшая форма команды
awk подразумевает описание основного действия в одинарных кавычках и фигурных скобках с указанием после него целевого файла.Выглядеть она может так:
awk '{action}' your_file_name.txt
Когда вам нужно найти текст, соответствующий конкретному шаблону, или же конкретное слово в тексте, команда принимает следующий вид:
awk '/regex pattern/{action}' your_file_name.txt
Создание образца файла
Для создания файла в командной строке используется команда
touch. Например: touch filename.txt, где filename – это произвольное имя файла.Затем можно с помощью команды
open (open filename.txt) запустить обработчик текста вроде TextEdit, который позволит внести в файл нужное содержимое.Предположим, у вас есть текстовый файл information.txt, содержащий данные, разделённые по столбцам.
Выглядеть этот файл может так:
firstName lastName age city ID
Thomas Shelby 30 Rio 400
Omega Night 45 Ontario 600
Wood Tinker 54 Lisbon N/A
Giorgos Georgiou 35 London 300
Timmy Turner 32 Berlin N/A
В приведённом примере мы видим по одному столбцу для
firstName, lastName, age, city и ID.В любой момент можно просмотреть вывод содержимого вашего файла, выполнив
cat text_file, где text_file представляет имя файла.Вывод всего содержимого файла
Для вывода всего содержимого файла в качестве действия в фигурных скобках нужно указать
print $0.Сработает эта команда аналогично ранее упомянутой
cat.awk '{print $0}' information.txt
Вывод:
firstName lastName age city ID
Thomas Shelby 30 Rio 400
Omega Night 45 Ontario 600
Wood Tinker 54 Lisbon N/A
Giorgos Georgiou 35 London 300
Timmy Turner 32 Berlin N/A
Если захотите добавить нумерацию строк, то нужно будет дополнить действие переменной
NR:awk '{print NR,$0}' information.txt
1 firstName lastName age city ID
2
3 Thomas Shelby 30 Rio 400
4 Omega Night 45 Ontario 600
5 Wood Tinker 54 Lisbon N/A
6 Giorgos Georgiou 35 London 300
7 Timmy Turner 32 Berlin N/A
Вывод конкретных столбцов
При использовании
awk можно указывать для вывода конкретные столбцы.Вывод первого производится следующей командой:
awk '{print $1}' information.txt
Вывод:
Thomas
Omega
Wood
Giorgos
Timmy
Здесь
$1 означает первое поле, то есть в данном случае первый столбец.Для вывода второго столбца используется
$2:awk '{print $2}' information.txt
Вывод:
lastName
Shelby
Night
Tinker
Georgiou
Turner
По умолчанию начало и конец каждого столбца
awk определяет по пробелу.Для вывода большего числа столбцов, например, первого и четвёртого, нужно выполнить:
awk '{print $1, $4}' information.txt
Вывод:
firstName city
Thomas Rio
Omega Ontario
Wood Lisbon
Giorgos London
Timmy Berlin
Здесь
$1 представляет первое поле ввода (первый столбец), а $4 четвёртое. При этом они отделяются запятой, чтобы вывод разделялся пробелом и был более читаемым.Для вывода последнего поля (последнего столбца) также можно использовать команду
$NF, представляющую последнее поле записи:awk '{print $NF}' information.txt
Вывод:
ID
400
600
N/A
300
N/A
Вывод конкретных строк столбца
Также можно указывать для вывода строку определённого столбца:
awk '{print $1}' information.txt | head -1
Вывод:
FirstName
Разделим эту команду на две части. Сначала
awk '{print $1}' information.txt выводит первый столбец. Затем её результат (который мы видели выше) с помощью символа | передаётся на обработку команде head, где аргумент -1 указывает на выбор первой строки столбца.Для вывода двух строк команда будет такой:
awk '{print $1}' information.txt | head -2
Вывод:
FirstName
Dionysia
Вывод строк с заданным шаблоном
Вы можете выводить строку, начинающуюся с заданной буквы. Например:
awk '/^O/' information.txt
Вывод:
Omega Night 45 Ontario 600
Эта команда выбирает все строки с текстом, начинающимся на
O.Действие команды начинается с символа
^, который указывает на начало строки. После этого прописывается буква, с которой нужная вам строка должна начинаться.По аналогичному принципу можно выводить строку, завершающуюся конкретным шаблоном:
awk '/0$/' information.txt
Вывод:
Thomas Shelby 30 Rio 400
Omega Night 45 Ontario 600
Giorgos Georgiou 35 London 300
Эта команда выводит строки, оканчивающиеся на
0 – здесь с помощью символа $ мы указываем, как должна заканчиваться нужная строка.При этом её можно несколько изменить:
awk '! /0$/' information.txt
Символ
! используется в качестве приставки «НЕ», а значит, в этом случае будут выбраны строки, которые не оканчиваются на 0.firstName lastName age city ID
Wood Tinker 54 Lisbon N/A
Timmy Turner 32 Berlin N/A
Использование регулярных выражений
Для вывода слов, содержащих определённые буквы, а также слов, соответствующих указанному шаблону, мы снова используем прямые слэши.
К примеру, если нас интересуют слова, содержащие
io, мы пишем:awk ' /io/{print $0}' information.txt
Вывод:
Thomas Shelby 30 Rio 400
Omega Night 45 Ontario 600
Giorgos Georgiou 35 London 300
Мы получили строки, в которых содержатся слова, содержащие
io.Теперь предположим, что в файле есть дополнительный столбец
department:firstName lastName age city ID department
Thomas Shelby 30 Rio 400 IT
Omega Night 45 Ontario 600 Design
Wood Tinker 54 Lisbon N/A IT
Giorgos Georgiou 35 London 300 Data
Timmy Turner 32 Berlin N/A Engineering
Для поиска всей информации о людях, работающих в
IT, нужно указать искомую строку между //:awk '/IT/' information.txt
Вывод:
Thomas Shelby 30 Rio 400 IT
Wood Tinker 54 Lisbon N/A IT
А что, если мы хотим увидеть только имена и фамилии сотрудников из
IT?Тогда можно указать столбец так:
awk '/IT/{print $1, $2}' information.txt
Вывод:
Thomas Shelby
Wood Tinker
В этом случае отобразятся только первый и второй столбцы строк, содержащих
IT.При поиске слов, содержащих конкретный шаблон, бывают случаи, когда требуется использовать экранирующий символ:
awk '/N\/A$/' information.txt
Вывод:
Wood Tinker 54 Lisbon N/A
Timmy Turner 32 Berlin N/A
Я хотела найти строки, оканчивающиеся на
N/A. Поэтому при указании критериев поиска в ' // ', как это показывалось выше, мне пришлось использовать между N/A символ перехода \. В противном случае возникла бы ошибка.Использование операторов сравнения
Если вы, предположим, захотите найти всю информацию о сотрудниках в возрасте до 40 лет, то нужно будет использовать оператор сравнения
< так:awk '$3 < 40 { print $0 }' information.txt
Вывод:
Thomas Shelby 30 Rio 400
Giorgos Georgiou 35 London 300
Timmy Turner 32 Berlin N/A
В выводе представлена информация о людях моложе 40.
Заключение
Вот и всё. Теперь у вас есть необходимая основа для начала работы с
awk и управления текстовыми данными.Благодарю за чтение и успехов вам в обучении!
Комментарии (12)

randomsimplenumber
13.05.2022 18:42+1
A1EF
14.05.2022 01:04Тоже добавлю в копилочку неплохую шпаргалку: https://learnxinyminutes.com/docs/awk/

pfemidi
13.05.2022 21:54+4Дочитав до слов «символ перехода» я на некоторое время завис. Но продолжив чтение я понял что имеется в виду «escape character». Посмотрел оригинал и понял что я правильно предположил.

shovdmi
14.05.2022 09:42+2Для создания файла в командной строке используется команда
touchФормально говоря, утилита touch не для создания файла, а обновления его timestamp. То что она создает файл это её дополнительная фича. Ее может и не быть в системе, или могут отсутствовать права на ее запуск.
man touch touch - change file timestampsсоздать можно перенаправлением вывода
> newfile.txt

orl1an1k
14.05.2022 20:36+2Добавлю из своей практики полезные кейсы.
Ключом -F можно указывать разделитель столбцов:
awk -F '*' '{print $1}'Также полезно применять арифметические операторы к переменным. Вывод предпоследнего столбца:awk '{print $NF-1}'А также пару крутых однострочников которые показывают всю прелесть awk с другими команднами.
Вывод потребления памяти с сортировкой из ps:ps axo rss,comm,pid | awk '{ proc_list[Потребление SWAP:1/=1024;printf "%.0fMB\t",$1}{print $2}'
for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 2 -n -r | head

maslyaev
14.05.2022 23:02Таблички в текстовых файликах по колоночкам? Серьёзно? Почему хотя бы не csv или тот же jsonl?

CtrlAltDragon
15.05.2022 13:55+3Ну так awk, как и всё прочее — ориентирован на чтение глазами живым человеком, которому таблицы с колонками читать проще, чем JSON.
Если бы в терминале ps печатал не такую таблицу:% ps PID TTY TIME CMD 1190 pts/5 00:00:00 ps 8340 pts/5 00:00:01 zsh
А вот такой страх и ужас:% ps | sed 's/^[ \t]*//g' | tr -s ' ' ',' | python -c 'import csv, json, sys; print(json.dumps([dict(r) for r in csv.DictReader(sys.stdin)]))' | jq | tee [ { "PID": "2750", "TTY": "pts/5", "TIME": "00:00:00", "CMD": "ps" }, { "PID": "2751", "TTY": "pts/5", "TIME": "00:00:00", "CMD": "sed" }, { "PID": "2752", "TTY": "pts/5", "TIME": "00:00:00", "CMD": "tr" }, { "PID": "2753", "TTY": "pts/5", "TIME": "00:00:00", "CMD": "python" }, { "PID": "2754", "TTY": "pts/5", "TIME": "00:00:00", "CMD": "jq" }, { "PID": "8340", "TTY": "pts/5", "TIME": "00:00:02", "CMD": "zsh" } ]
то ни о каких FreeBSD, Linux и прочих Unix-like системах мы бы сейчас и не слышали.

randomsimplenumber
15.05.2022 20:13-1Почему хотя бы не csv или тот же jsonl?
Выхлоп почти любой команды достаточно просто преобразовать в вид, понятный awk. А вот преобразовать произвольный текст в json не всегда просто.
dlinyj
Моя производственная практика показала, что эти древние команды BASH используется очень часто. И умение эффективно использовать их выводит на новый уровень.
И, как по мне, хоть уже тысячи раз говорили про всевозможные bash команды, освежить в памяти всегда полезно. Тем более что часто возвращаюсь к различным публикациям на хабре. Огромное спасибо за перевод!
lrrr11
строго говоря bash - это bash, а awk - это awk)
dlinyj
Согласен. Я в том ключе, что базовые команды.