6 способов фильтрации текста с помощью команды awk в Linux
Перейти по ссылкам
- Сопоставление текста с помощью регулярных выражений
- Выберите строки по номеру строки, длине, количеству полей или последнему полю
- Сравнить и фильтровать числовые значения полей
- Захват диапазонов строк между совпадающими шаблонами
- Исключить нежелательные или дублирующие записи
- Переформатировать текст, выбрав определённые столбцы
Команда awk является универсальным инструментом обработки текста в Linux. Она фильтрует и обрабатывает файлы с помощью шаблонов, условий и действий. Она поддерживает широкий спектр сценариев, что делает простым извлечение определенных данных из журналов, файлов конфигурации или любых текстовых файлов.
Вот несколько популярных способов фильтрации текста с помощью awk. Они включают поиск с использованием регулярных выражений, выбор строк и полей, числовую фильтрацию и многое другое.
Соответствие текста с использованием регулярных выражений
Хотя регулярные выражения известны своей крутой кривой обучения, они являются швейцарским армейским ножом для работы с текстом. Используя их вместе с такими инструментами, как awk, вы можете искать шаблоны, от простых до сложных, по целым файлам за миллисекунды.
Давайте начнем с базового синтаксиса:
awk '/pattern/ {print}' filename`
Косые черты указывают awk, что вы используете регулярное выражение, а фигурные скобки содержат действие, которое нужно выполнить при совпадении. Например, вы можете вывести все записи журнала, содержащие «error», из файла журнала с помощью этого:
awk '/error/ {print}' syslog.log
Эта однострочная команда захватывает каждую строку, содержащую слово error, но regex позволяет идти дальше. Например, чтобы найти строки, начинающиеся с INFO или WARN, используйте эту команду:
awk '/^(INFO|WARN)/ {print}' syslog.log
Здесь символ | действует как оператор ИЛИ, а карет ^соответствует началу строки.
То, что мне нравится в регулярных выражениях, так это то, что они выходят за пределы точных слов, позволяя использовать подстановочные знаки для более сложного поиска. Например, вы можете найти адреса электронной почты в текстовом файле с помощью этого шаблона:
awk '/[a-zA-Z0-9]+@[a-zA-Z0-9]+.[a-zA-Z]+/ {print}' contacts.txt
Этот шаблон соответствует последовательностям букв и цифр, за которыми следует символ @, затем снова буквы и цифры, точка и, наконец, снова буквы. Хотя он не идеален для всех форматов электронной почты, он охватывает большинство распространённых вариантов.
Вы также можете использовать оператор тильда (~) для более точного поиска в определённых полях. Этот подход очень эффективен для структурированных данных. Например, если вы хотите искать ERROR только в третьем поле каждой строки, вы можете использовать следующее:
awk '$3 ~ /ERROR/ {print}' system.log
Этот подход делает его более точным, чем поиск по всей строке. Кроме того, если важна чувствительность к регистру, просто используйте функцию tolower() следующим образом:
awk 'tolower($0) ~ /error/ {print}' mixed_case.log
Эта команда преобразует каждую строку в строчные буквы перед поиском, что позволяет ей находить ERROR, Error, error и любые другие варианты написания с разным регистром.
Выберите строки по номеру строки, длине, количеству полей или последнему полю
Иногда вам нужны определённые строки в зависимости от их позиции или характеристик, а не содержания. awk прекрасно справляется с такими ситуациями благодаря своим встроенным переменным, которые позволяют фильтровать строки по позиции или структуре. К этим встроенным переменным относятся NR, length(), NF и $NF.
Начнем с переменной NR. Она обозначает Number of Record (или просто номер строки). awk увеличивает её для каждой прочитанной строки. Вы можете использовать это, чтобы получать определенные строки или диапазоны.
Чтобы вывести первые 10 строк файла, используйте:
awk 'NR <=10 {print}' largefile.txt
Аналогично, чтобы получить все строки с чётными номерами, используйте 2:
awk 'NR % 2 == 0 {print}' file.txt
Для диапазонов вы можете объединять несколько условий NR с помощью оператора && следующим образом:
awk 'NR >= 50 && NR <= 100 {print}' file.txt
Это выводит строки с 50 по 100. Вы также можете использовать функцию length() вместе с awk при работе с файлами с неконсистентным форматированием или когда вы хотите отфильтровать пустые строки.
Например, чтобы посчитать символы с помощью функции length() и затем отображать только строки длиной более 80 символов, используйте:
awk 'length($0) > 80 {print}' code.py
Теперь давайте поговорим о другой часто используемой переменной, NF, которая обозначает количество полей. Используя эту переменную, awk автоматически разбивает каждую строку на поля на основе разделителя (по умолчанию это пробелы или табуляции).
Например, для CSV-файлов или структурированных данных вы можете использовать переменную NF, чтобы подсчитывать поля (столбцы). Вы можете фильтровать данные в зависимости от того, сколько полей содержит каждая строка:
awk 'NF == 5 {print}' customer_data.csv
Это оставляет только строки с ровно 5 полями, помогая вам заметить неполные записи. Чтобы сделать наоборот и выводить только строки, которые не имеют ровно 5 полей, используйте оператор != вместо ==. Кроме того, чтобы вывести строки с как минимум 5 полями (столбцами), используйте оператор >=.
В то время как NF указывает, сколько полей существует, $NF даёт значение самого последнего поля. Переменная $NF представляет собой последнее поле в каждой строке, независимо от количества полей. Это чрезвычайно полезно при работе с файлами, где количество столбцов может меняться.
Возьмите эту команду:
awk '$NF == "COMPLETED" {print}' task_list.txt
Это находит все строки, оканчивающиеся на COMPLETED, даже если некоторые строки имеют 3 поля, а другие — 7.
Вы также можете объединить все эти условия вместе:
awk 'length($0) > 50 && NF >= 4 {print}' mixed_data.txt
Эта команда выводит только строки, длина которых превышает 50 символов и содержащие как минимум 4 поля. Она гарантирует, что в выводе не будет коротких или неполных строк.
Сравнить и фильтровать числовые значения полей
awk достаточно умён, чтобы обрабатывать поля, содержащие числа, как настоящие числа, а не просто текст. Это означает, что вы можете выполнять математические сравнения без каких-либо специальных функций преобразования, открывая целый новый мир возможностей фильтрации.
Итак, допустим, у вас есть CSV с результатами студентов, и вы хотите вернуть только тех студентов, которые набрали более 80 баллов. Это можно сделать следующим образом:
awk -F, '$2 > 80 {print $1, $2}' scores.csv
Здесь мы используем -F, чтобы указать awk, что поля разделены запятыми. $2 относится ко второму полю или колонке (оценке), а $1 — это имя.
При работе с текстовыми файлами знаки процентов могут вызывать проблемы, если символ % включен в поле. Вы можете удалить его с помощью функции gsub():
awk '{gsub(/%/, "", $4); if($4 > 75) print}' performance.txt
Эта команда удаляет символ % из четвертого поля, а затем проверяет, превышает ли оставшееся число 75.
Вы также можете использовать несколько условий с логическими операторами. Например, если вы хотите извлечь значения продаж из CSV-файла, которые находятся между $500 и $2000, выполните:
awk -F, '$3 > 500 && $3 < 2000 {print}' sales.csv
Вы также можете объединять условия с помощью оператора || (ИЛИ). Например, чтобы найти записи, где продажи либо очень высокие, либо очень низкие, используйте:
awk -F, '$3 > 5000 || $3 < 100 {print}' sales.csv
Помимо числовых сравнений, вы также можете использовать несколько условий для сопоставления определенного текста, проверки дат или исключения нежелательных записей.
Вы также можете комбинировать && и ||. Однако скобки необходимы для правильного управления логикой. Допустим, вы хотите найти аккаунты, которые либо АКТИВНЫЕ, либо В ОЖИДАНИИ, но только если их баланс превышает $1000. Вы бы написали:
awk -F, '($2 == "ACTIVE" || $2 == "PENDING") && $3 > 1000' accounts.csv
Без скобок приоритет операторов изменил бы смысл фильтра.
Захват диапазонов строк между совпадающими шаблонами
Большинство пользователей Linux знакомы с использованием grep для извлечения конкретной информации. Однако awk также может выбирать диапазон строк, начиная с строки, которая соответствует start_pattern, и заканчивая строкой, которая соответствует end_pattern.
Синтаксис элегантно прост:
awk '/start_pattern/,/end_pattern/' filename
Это захватывает начальную строку, все строки между ними и конечную строку. Если вы хотите исключить сами маркеры, вы можете использовать подход на основе флагов, например, такой:
awk '/BEGIN/{flag=1; next} /END/{flag=0} flag' logfile.txt
Кроме того, мы можем захватывать полные блоки ошибок, которые начинаются с указанного текста и заканчиваются на следующей пустой строке.
awk '/ERROR:/,/^$/ {print}' application.log
Здесь awk начнёт выводить строки, когда встретит строку, содержащую «ERROR:», и продолжит до первой пустой строки.
Исключить нежелательные или дублирующиеся записи
Очистка данных часто означает удаление того, что вам не нужно. awk предоставляет простые способы фильтрации шума и удаления избыточных данных.
Оператор NOT (!) является вашим основным инструментом для исключения. Вы можете поставить его перед любой шаблон или условие, чтобы инвертировать совпадение, заставляя awk выполнять действие для всех строк, которые не соответствуют.
Например, предположим, что вы хотите исключить из файла журнала вашего приложения все сообщения, содержащие DEBUG. Используйте следующее:
awk '!/DEBUG/' application.log
Эта команда выводит каждую строку из файла application.log, если она не содержит слово DEBUG.
Вы также можете сочетать это с условиями на основе полей, например, вы можете просмотреть весь трафик, который не поступил с вашего внутреннего IP-адреса для мониторинга.
awk '$1 != "10.0.0.5"' access.log
Аналогично, ещё одной полезной операцией awk является фильтрация комментариев (строк, начинающихся с #) и пустых строк из конфигурационного файла. Для этого используйте:
awk '!/^#/ && NF > 0 {print}' config.ini
Это пропускает строки, начинающиеся с #, и также удаляет пустые строки.
Вы также можете удалить дубликаты на основе конкретного поля. Например, предположим, что у вас есть CSV-файл contact_list с тремя столбцами: ID, Name и Email. Чтобы сохранить только первую запись для каждого уникального адреса электронной почты (в третьем столбце), используйте:
awk '!seen[$3]++ {print}' contact_list.csv
Кроме того, вы можете исключить нечувствительное к регистру исключение с помощью функции tolower():
Переформатировать текст, выбрав определённые столбцы
Исходные данные часто поступают в структуре, которая вам на самом деле не нужна, и awk позволяет легко перестроить их в нечто более полезное. Вы можете выбрать определённые столбцы, изменить их порядок или даже объединить их в новые поля.
Например, если вы хотите вывести только второй и пятый столбцы из файла, вы можете использовать:
awk -F, '{print $2, $5}' sales.csv
Если вы хотите изменить порядок столбцов, поменяйте местами $5 и $2.
По умолчанию awk разделяет вывод пробелами, но вы можете вставить свой собственный разделитель, например, символ вертикальной черты.
awk '{print $1 "|" $3}' data.txt
При работе с CSV-файлами первая строка часто является заголовком. Вы можете пропустить её с помощью NR > 1 и изменить порядок столбцов, чтобы сначала отображался адрес электронной почты, а затем имя.
awk -F, 'NR > 1 {print $3, "->", $1, $2}' contacts.csv
Вы также можете объединять поля для создания новых, например, соединяя имя и фамилию в полное имя перед отправкой электронной почты.
awk -F, '{print $1 " " $2, $3}' contacts.csv
Наконец, если вы хотите, чтобы вывод выглядел более четким, вы можете добавить собственный заголовок перед данными, используя блок BEGIN.
awk 'BEGIN {print "Name,Email"} {print $1 "," $2}' data.txt
Эти простые примеры достаточно, чтобы начать перерабатывать текст в формат, который лучше соответствует вашим потребностям.
Помните, что awk отлично справляется с обработкой структурированного текста, с любыми данными, имеющими последовательные шаблоны или разделение на поля. Чем более регулярна структура ваших данных, тем мощнее становится awk. А когда вы комбинируете эти методы фильтрации с другими инструментами Linux через конвейеры, вы создаете невероятно эффективные рабочие процессы для обработки текста.







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