Команда awk: вывод полей, разделитель -F и условные шаблоны

Тестовая средаСемейство RHELAlmaLinux 9.8Учётная запись rootПроверено 2026-10-29

Команда awk — это инструмент Linux, который читает текстовый файл строка за строкой, разбивает каждую строку на поля по пробелам или указанному вами разделителю и выбирает только поля строк, соответствующих условию, чтобы вывести их или выполнить вычисления. На сервере AlmaLinux 9 мы подсчитали запросы по IP-адресам и количество по кодам состояния в примере журнала доступа веб-сервера одной строкой, соединённой конвейером с sort, и оказалось, что все три ответа 404 из двенадцати строк были запросами к wp-login.php и .env с одного IP.

Приведённый ниже вывод получен под учётной записью root в рабочей папке на сервере AlmaLinux 9.8. Журнал доступа, список учётных записей, записи о продажах и файл с баллами — это примеры, созданные для теста, а IP-адреса и имена учётных записей в них тоже являются примерами.

1️⃣ Основы использования команды awk

  • ↪️ Номера полей и print

awk разбивает прочитанную строку по пробелам и нумерует поля с начала как $1, $2, $3. Мы проверили это на файле scores.txt, где имя, результат и баллы разделены пробелами.

cat scores.txt
alice   pass  82
bob     fail  47
carol   pass  91
dave    pass  68
erin    fail  55

Фигурные скобки внутри одинарных кавычек содержат действие для каждой строки, а если после print перечислить номера полей через запятую, будут выведены только эти поля. При выводе первого и третьего полей остаются только имя и баллы.

awk '{print $1, $3}' scores.txt
alice 82
bob 47
carol 91
dave 68
erin 55

Если убрать запятую между полями и написать $1 $3, два значения выводятся слитно, без пробела. Запятая в print вставляет разделитель вывода (по умолчанию один пробел), а значения, написанные рядом без запятой, склеиваются в одну строку.

awk '{print $1 $3}' scores.txt
alice82
bob47
carol91
dave68
erin55

NR — это номер прочитанной к этому моменту строки, NF — число полей в ней. $NF означает последнее поле, поэтому последний столбец можно выбрать, даже если число полей в строках разное.

awk '{print NR, NF, $NF}' scores.txt
1 3 82
2 3 47
3 3 91
4 3 68
5 3 55

Журнал доступа веб-сервера тоже разделён пробелами, поэтому поля выбираются так же. Номера полей первой строки тестового журнала приведены ниже.

ПолеЗначение в первой строкеНазначение
$1192.0.2.10IP клиента
$4[29/Oct/2026:00:01:12Дата и время запроса
$6"GETМетод запроса (с двойной кавычкой впереди)
$7/index.htmlURL запроса
$9200Код статуса
$105120Отправленные байты
$11"-"Предыдущая страница (Referer)
$12~$15"Mozilla/5.0 (X11; Linux x86_64)"User agent (делится на каждом пробеле)

Мы вывели $1, $7 и $9, то есть IP клиента, URL запроса и код состояния.

awk '{print $1, $7, $9}' access.log
192.0.2.10 /index.html 200
198.51.100.7 /about.html 200
192.0.2.10 /images/logo.png 200
203.0.113.25 /wp-login.php 404
203.0.113.25 /wp-login.php 404
192.0.2.10 /contact.html 200
198.51.100.7 /old-page.html 301
203.0.113.25 /.env 404
192.0.2.44 /index.html 200
198.51.100.7 /api/search?q=awk 500
192.0.2.44 /images/logo.png 304
192.0.2.10 /index.html 200

Столбец с пробелами в значении, например user agent, разбивается на несколько полей. NF во всех трёх первых строках равно 15, а $NF — последний фрагмент user agent.

awk '{print NF, $NF}' access.log | head -3
15 x86_64)"
15 x86_64)"
15 x86_64)"

2️⃣ Задание разделителя через awk -F

  • ↪️ Разделители: двоеточие, запятая и регулярное выражение

Для файла, столбцы которого разделены не пробелом, укажите этот символ после -F. При выводе $1 без -F из списка учётных записей users.txt, составленного по образцу /etc/passwd, большинство строк вышло целиком.

awk '{print $1}' users.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
nobody:x:65534:65534:Kernel
user:x:1000:1000:Example
deploy:x:1001:1001:Deploy
backup:x:1002:1002::/home/backup:/sbin/nologin

Разделитель по умолчанию — пробел, поэтому строка, соединённая только двоеточиями, содержит одно поле. Только строки nobody, user и deploy с пробелом в столбце описания обрезаются на этом пробеле.

С -F: двоеточие становится разделителем, и имя учётной записи ($1) и оболочка входа ($7) разделяются.

awk -F: '{print $1, $7}' users.txt
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
nobody /sbin/nologin
user /bin/bash
deploy /bin/bash
backup /sbin/nologin

CSV-файлы с запятыми разбиваются через -F,. При выводе товара и количества из записей о продажах sales.csv заголовок в первой строке (item qty) разбивается так же и выводится вместе с ними.

awk -F, '{print $2, $3}' sales.csv
item qty
keyboard 2
mouse 5
monitor 1
keyboard 1
cable 10
mouse 2
monitor 2

-F, не подходит для CSV с запятыми внутри столбцов в двойных кавычках. В quoted.csv с запятыми в столбце товара поля разбиваются и на запятых внутри кавычек, и во втором поле остаётся только начало названия товара.

awk -F, '{print $2}' quoted.csv
item
"cable
keyboard

Для таких файлов официальное руководство GNU Awk описывает переменную FPAT. Если вместо разделителя записать форму одного поля регулярным выражением, столбец в кавычках станет одним полем.

awk -v FPAT='([^,]*)|("[^"]*")' '{print $2}' quoted.csv
item
"cable, usb"
keyboard

Чтобы использовать несколько разделителей, запишите их регулярным выражением в квадратных скобках. Если разделители — двоеточие и косая черта, $NF становится последним именем в пути оболочки входа (bash, nologin).

awk -F'[:/]' '{print $1, $NF}' users.txt
root bash
bin nologin
daemon nologin
nobody nologin
user bash
deploy bash
backup nologin

3️⃣ Условные шаблоны команды awk

  • ↪️ Регулярные выражения, сравнения и NR

Даже при выборе полей выводятся все строки, поэтому, чтобы оставить только нужные, поставьте условие (шаблон) перед фигурными скобками. Строка между косыми чертами выбирает только содержащие её строки, а если действие опущено, выводится вся строка.

awk '/wp-login/' access.log
203.0.113.25 - - [29/Oct/2026:00:04:51 +0000] "POST /wp-login.php HTTP/1.1" 404 196 "-" "Mozilla/5.0 (X11; Linux x86_64)"
203.0.113.25 - - [29/Oct/2026:00:04:52 +0000] "POST /wp-login.php HTTP/1.1" 404 196 "-" "Mozilla/5.0 (X11; Linux x86_64)"

Выбранные строки те же, что и у команды grep, а awk сразу выбирает из них поля и выводит их. Если передать по конвейеру в awk те же две строки, выбранные через grep, останутся только IP и код состояния.

grep wp-login access.log | awk '{print $1, $9}'
203.0.113.25 404
203.0.113.25 404

Значения полей сравниваются через ==, !=, >, >=, <, <=. Мы выбрали только строки с кодом состояния ($9) 404 и вывели IP и URL запроса.

awk '$9 == 404 {print $1, $7}' access.log
203.0.113.25 /wp-login.php
203.0.113.25 /wp-login.php
203.0.113.25 /.env

При сравнении со строкой заключите значение в двойные кавычки. Мы выбрали только имена, у которых второе поле равно pass.

awk '$2 == "pass" {print $1}' scores.txt
alice
carol
dave

Числовое сравнение нужно для выбора по диапазону, например по номерам учётных записей (UID). При выборе записей с UID от 1000 и выше вместе с обычными записями попадает и nobody с UID 65534.

awk -F: '$3 >= 1000 {print $1, $3}' users.txt
nobody 65534
user 1000
deploy 1001
backup 1002

Два условия объединяются через &&. Если добавить условие меньше 65534, nobody исчезает, и остаются только три обычные учётные записи и их домашние папки.

awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $6}' users.txt
user /home/user
deploy /home/deploy
backup /home/backup

[~] проверяет, соответствует ли поле регулярному выражению, а [!~] — что не соответствует. Если выбрать записи, у которых оболочка входа ($7) заканчивается на bash, и записи без nologin, получаются те же три записи.

awk -F: '$7 ~ /bash$/ {print $1}' users.txt
root
user
deploy
awk -F: '$7 !~ /nologin/ {print $1, $7}' users.txt
root /bin/bash
user /bin/bash
deploy /bin/bash

Условие NR выбирает по номеру строки. NR > 1 убирает строку заголовка CSV, и остаются только записи о продажах.

awk -F, 'NR > 1 {print $2, $3}' sales.csv
keyboard 2
mouse 5
monitor 1
keyboard 1
cable 10
mouse 2
monitor 2

Вывод других команд тоже можно передать по конвейеру и разбить так же. При выборе размера файла ($5) и имени ($9) из вывода ls -l первая строка вышла пустой, потому что в первой строке ls -l, [total 24], нет пятого и девятого полей.

ls -l | awk '{print $5, $9}'

1567 access.log
79 quoted.csv
207 sales.csv
85 scores-copy.txt
85 scores.txt
315 users.txt

С NR > 1 первая строка исчезает, и остаются только размеры и имена файлов.

ls -l | awk 'NR > 1 {print $5, $9}'
1567 access.log
79 quoted.csv
207 sales.csv
85 scores-copy.txt
85 scores.txt
315 users.txt

4️⃣ awk BEGIN, END, сумма и среднее

  • ↪️ Переменные и форматы вывода printf

Блок BEGIN выполняется один раз перед чтением первой строки, а блок END — один раз после обработки последней. Для суммы прибавляйте значение к переменной в каждой строке и выводите её в END. Схема ниже показывает порядок, который awk проходит для каждой строки при суммировании сумм из записей о продажах.

🔁 Порядок построчной обработки sales.csv в awk
Поясняющая схема
🔁 Порядок обработки
$ awk -F, 'NR > 1 {t += $3 * $4} END {printf "total %.2f\n", t}' sales.csv
① Прочитанная строкаNR = 1date,item,qty,priceNR = 22026-10-01,keyboard,2,45.00NR = 32026-10-01,mouse,5,19.90NR = 82026-10-04,monitor,2,189.00Больше нет строк для чтенияСтрока 8 — последняя.
② Разбивка на поля (-F,)$1date$2item$3qty$4priceСтрока заголовка разбивается так же.$12026-10-01$2keyboard$32$445.00$3 количество, $4 цена за единицу$12026-10-01$2mouse$35$419.90$3 количество, $4 цена за единицу$12026-10-04$2monitor$32$4189.00$3 количество, $4 цена за единицуНет строки для разбивкиБлок END не читает строки.
③ Шаблон и действиеNR > 1 ложьДействие пропускается.t = (пусто)NR > 1 истинаt += 2 * 45.00t = 90NR > 1 истинаt += 5 * 19.90t = 189.5NR > 1 истинаt += 2 * 189.00t = 886.3Выполнение ENDtotal 886.30printf выводит t с двумя знаками после запятой.
Первая строка — заголовок, поэтому NR > 1 ложно, и awk переходит к следующей строке без действия.
Со второй строки шаблон истинен, и 90, произведение количества на цену за единицу, прибавляется к переменной t.
Переменная t сохраняет значение между строками, поэтому сумма до третьей строки равна 189.5.
Строки 4–7 проходят тот же порядок, и к последней, восьмой строке t равно 886.3.
После обработки последней строки блок END выполняется один раз, и printf выводит total 886.30.

Сумма всех отправленных байтов ($10) в журнале доступа составила 41298 байт. Впервые используемая переменная начинается с пустого значения (как число — 0), поэтому задавать 0 отдельно не нужно.

awk '{sum += $10} END {print sum}' access.log
41298

Если выводить сумму не в END, а в действии для каждой строки, при чтении каждой строки появляется накопленная сумма. Если при каждом прибавлении произведения количества на цену выводить номер строки и t, получится семь строк без заголовка, а 886.3 в последней строке — общая сумма.

awk -F, 'NR > 1 {t += $3 * $4; print NR, t}' sales.csv
2 90
3 189.5
4 378.5
5 423.5
6 468.5
7 508.3
8 886.3

Среднее вычисляется в END делением суммы на число строк. Сумма баллов в пяти строках составила 343, среднее — 68.6.

awk '{total += $3; n++} END {print total, n, total / n}' scores.txt
343 5 68.6

BEGIN нужен, чтобы один раз вывести строку заголовка над результатами. Над товарами и суммами (количество × цена за единицу) строка item total появляется только один раз.

awk -F, 'BEGIN {print "item", "total"} NR > 1 {print $2, $3 * $4}' sales.csv
item total
keyboard 90
mouse 99.5
monitor 189
keyboard 45
cable 45
mouse 39.8
monitor 378

Разделитель вывода меняется переменной OFS в BEGIN. Если задать OFS запятую, на месте запятых в print ставится запятая вместо пробела, и список учётных записей выводится в формате CSV.

awk 'BEGIN {FS = ":"; OFS = ","} {print $1, $3, $7}' users.txt
root,0,/bin/bash
bin,1,/sbin/nologin
daemon,2,/sbin/nologin
nobody,65534,/sbin/nologin
user,1000,/bin/bash
deploy,1001,/bin/bash
backup,1002,/sbin/nologin

Для выравнивания столбцов используйте printf. %-10s — строка с выравниванием влево на 10 позиций, %3d — целое число на 3 позиции, %8.2f — число на 8 позиций с двумя знаками после запятой.

awk -F, 'NR > 1 {printf "%-10s %8.2f\n", $2, $3, $3 * $4}' sales.csv
keyboard     2    90.00
mouse        5    99.50
monitor      1   189.00
keyboard     1    45.00
cable       10    45.00
mouse        2    39.80
monitor      2   378.00

В отличие от print, printf не переводит строку, поэтому в конце формата нужно написать [\n]. Без [\n] названия товаров сливаются в одну строку.

awk -F, 'NR > 1 {printf "%s ", $2}' sales.csv
keyboard mouse monitor keyboard cable mouse monitor

5️⃣ Анализ журналов и опции команды awk

  • ↪️ Подсчёт IP клиентов и кодов состояния, сводка опций

🔲 Анализ журналов

Прибавление к одной переменной даёт только одну сумму, поэтому для подсчёта по IP или коду состояния собирайте значения в массив. n[$1]++ прибавляет 1 к элементу массива с ключом IP, а for (ip in n) в END достаёт собранные элементы по одному.

awk '{n[$1]++} END {for (ip in n) print n[ip], ip}' access.log | sort -rn
4 192.0.2.10
3 203.0.113.25
3 198.51.100.7
2 192.0.2.44

Порядок, в котором for (ip in n) достаёт элементы, не определён (по руководству GNU Awk), поэтому мы отсортировали их по числу запросов через sort -rn. Больше всего запросов у 192.0.2.10 — 4.

Количество по кодам состояния считается так же. Было 3 ответа 404 и 1 ответ 500.

awk '{n[$9]++} END {for (s in n) print s, n[s]}' access.log | sort
200 6
301 1
304 1
404 3
500 1

Если извлечь только коды состояния и передать их в sort и uniq -c, получится то же количество.

awk '{print $9}' access.log | sort | uniq -c
      6 200
      1 301
      1 304
      3 404
      1 500

Чтобы увидеть только ответы с ошибками, задайте условие на код состояния. Строки от 400 и выше — это три запроса, искавшие wp-login.php и .env, и одна ошибка 500.

awk '$9 >= 400 {print $9, $1, $7}' access.log
404 203.0.113.25 /wp-login.php
404 203.0.113.25 /wp-login.php
404 203.0.113.25 /.env
500 198.51.100.7 /api/search?q=awk

Сумма отправленных байтов по IP тоже считается в массиве. Больше всего получил 192.0.2.10 — 31340 байт.

awk '{b[$1] += $10} END {for (ip in b) print b[ip], ip}' access.log | sort -rn
31340 192.0.2.10
5120 192.0.2.44
4250 198.51.100.7
588 203.0.113.25

Поле времени ($4) можно сравнивать как строку. В строках с одинаковой датой и форматом порядок строк совпадает с порядком времени, поэтому мы выбрали только четыре запроса с 00:05 до 00:10.

awk '$4 >= "[29/Oct/2026:00:05" && $4 < "[29/Oct/2026:00:10" {print $4, $7}' access.log
[29/Oct/2026:00:05:30 /contact.html
[29/Oct/2026:00:07:02 /old-page.html
[29/Oct/2026:00:07:15 /.env
[29/Oct/2026:00:09:48 /index.html

🔲 Опции команды awk

📌 Основные опции: результаты из этой статьи

ОпцияНазначениеРезультат в этой статье
-F fsЗадаёт разделитель полей ввода-F: разделяет имя учётной записи ($1) и оболочку входа ($7) в users.txt, -F, выводит товар и количество из sales.csv вместе с заголовком (item qty)
-v var=valЗадаёт значение переменной перед запуском программыПередача переменной оболочки min через -v min=$min выводит шесть строк с отправленными байтами от 1000, с -v FPAT=… столбец в кавычках в quoted.csv становится одним полем
-i inplaceСохраняет вывод в исходный файл вместо экранаПосле gawk -i inplace на экране ничего не появляется, а копия scores.txt сокращается до двух столбцов, имени и баллов, с -v inplace::suffix=.bak прежнее содержимое остаётся в файле .bak
--versionВыводит сведения о версииПервая строка [awk --version] показывает версию GNU Awk 5

📎 Другие опции: по официальному руководству

ОпцияНазначение
-f program-fileЧитает программу AWK из файла вместо первого аргумента командной строки, -f можно указывать несколько раз
-e program-textИспользует текст в командной строке как исходный код программы AWK, можно сочетать с функциями библиотек, загруженными через -f или --include
-E fileПохожа на -f, но обрабатывается последней и блокирует присваивание переменных в командной строке, для скриптов #!
--traditionalРаботает в режиме совместимости, не распознаёт расширения GNU
--posixВключает режим совместимости с дополнительными ограничениями, например не распознаёт func, синоним function
--lintПредупреждает о сомнительных или плохо переносимых на другие реализации AWK конструкциях, с --lint=fatal предупреждения становятся фатальными ошибками
--dump-variablesЗаписывает в файл отсортированный список глобальных переменных с типами и итоговыми значениями, если файл не указан — в awkvars.out

🔲 Симулятор команды awk

В симуляторе ниже вы можете сами вводить команды awk для тех же тестовых файлов.

Симулятор команды awkGNU Awk 5
[root@server work]#
Небольшой интерпретатор awk, работающий только в вашем браузере. Четыре тестовых файла те же, что и при замерах, а клавишами ↑↓ можно вызвать предыдущие команды.

🔢 FAQ & рекомендуемые материалы

$min в одинарных кавычках оболочка не заменяет, и он доходит до awk без изменений, поэтому передавайте его опцией -v. Если записать 1000 в переменную оболочки min и передать -v min=$min, появятся шесть строк с отправленными байтами от 1000. Если заключить программу awk в двойные кавычки, оболочка сначала заменит пустым значением даже $1 в [print $1], и будет выведена вся строка.

С -i inplace GNU Awk сохраняет вывод в исходный файл вместо экрана. Когда мы запустили программу, выводящую первое и третье поля, для копии scores.txt через gawk -i inplace, на экране ничего не появилось, а файл сократился до двух столбцов, имени и баллов. Поскольку исходный файл сразу перезаписывается, добавление -v inplace::suffix=.bak сохраняет прежнее содержимое в файле .bak.

На сервере AlmaLinux 9 /usr/bin/awk был символической ссылкой на gawk, а первая строка [awk --version] показывала версию GNU Awk 5. На этом сервере оба имени запускают одну программу. Прежде чем использовать функции GNU Awk, такие как -i inplace или FPAT, проверьте через [awk --version], что это GNU Awk.

ℹ️ О партнёрских ссылках
Материалы этого сайта содержат партнёрские ссылки. Если посетитель покупает товар или услугу по такой ссылке, сайт получает комиссию от продавца. При этом сумма, которую платит покупатель (при акционных скидках сумма снижается ↓), не увеличивается. Указанные цены, скидки и наличие актуальны на момент написания и могут отличаться, поэтому перед покупкой уточняйте их у продавца. Товары выбираются и оцениваются по нашим собственным критериям, а комиссия не влияет ни на порядок, ни на содержание обзоров.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Докажите, что вы человек: 0   +   1   =