Мы не можем с уверенностью называть себя экспертами по управлению файлами Linux, не обладая навыками обработки текста. Три самых известных инструмента командной строки (grep, sed и awk) заслужили хорошую репутацию текстовых процессоров Linux. Они предустановлены во всех основных дистрибутивах операционных систем Linux, поэтому нет необходимости устанавливать их дополнительно.
Каждая команда grep, sed и awk имеет уникальные функции обработки текста, но в некоторых простых сценариях их функции могут быть аналогичными.
Например, все эти три команды могут легко проверить совпадения шаблона файла и отправить результаты запроса на вывод.
В этой статье является разберемся чем отличаются эти команды и в каких случаях использовать ту или иную команду.
Постановка задачи.
Для создания большей информативности и понятности, давайте определим образец текстового файла, на который мы будем ссылаться. Рассмотрим следующий созданный текстовый файл с именем SysLog.txt, в котором указаны различные системные действия на основе отметки времени.
$ cat SysLog.txt Timestamp Category Message 2597743202 INFO System Boot up started 2597743402 INFO Critical services boot up: Autorization 2597743502 INFO Successful system boot up 2597753502 INFO Userlist access request by user admin 2597763777 ERROR User annonymus access attempt on protected resource without credentials 2597763792 INFO System health check status: passed 2597763902 ERROR Requested resource not found 2597764422 INFO User admin logged out
Команда grep.
По определению, команда grep находит и печатает текст из файла на основе шаблона регулярного выражения. Это быстрое решение для получение или определения строки в целевом файле.
Синтаксис команды следующий:
grep [OPTION...] PATTERNS [FILE...]
В приведенном выше синтаксисе PATTERNS обозначают шаблон регулярного выражения, определенный пользователем, на который будет ссылаться команда grep.
Поиск соответствия шаблону регулярного выражения.
Допустим из файла, который мы создали ранее, мы хотим выделить все события ERROR, наша команда grep будет выглядеть следующим образом:
$ grep "ERROR" SysLog.txt 2597763777 ERROR User annonymus access attempt on protected resource without credentials 2597763902 ERROR Requested resource not found
Команда grep выполнит поиск любого появления строки ERROR в файле SysLog.txt перед выводом результатов на стандартный вывод.
Инвертирование поиска.
Предположим, мы хотим, чтобы были напечатаны все строки файла, кроме той, которая указана в команде grep. В этом случае используется опция -v.
$ grep -v "ERROR" SysLog.txt Timestamp Category Message 2597743202 INFO System Boot up started 2597743402 INFO Critical services boot up: Autorization 2597743502 INFO Successful system boot up 2597753502 INFO Userlist access request by user admin 2597763792 INFO System health check status: passed 2597764422 INFO User admin logged out
Печать предыдущих/последующих строк.
Чтобы напечатать 4 строки после совпадения строки ERROR:
$ grep -A 4 "ERROR" SysLog.txt 2597763777 ERROR User annonymus access attempt on protected resource without credentials 2597763792 INFO System health check status: passed 2597763902 ERROR Requested resource not found 2597764422 INFO User admin logged out
Для печати 4 строк до совпадения строки ERROR:
$ grep -B 4 "ERROR" SysLog.txt 2597743202 INFO System Boot up started 2597743402 INFO Critical services boot up: Autorization 2597743502 INFO Successful system boot up 2597753502 INFO Userlist access request by user admin 2597763777 ERROR User annonymus access attempt on protected resource without credentials 2597763792 INFO System health check status: passed 2597763902 ERROR Requested resource not found
Чтобы напечатать 3 строки до и после совпадения строки ERROR:
$ grep -C 3 "ERROR" SysLog.txt 2597743402 INFO Critical services boot up: Autorization 2597743502 INFO Successful system boot up 2597753502 INFO Userlist access request by user admin 2597763777 ERROR User annonymus access attempt on protected resource without credentials 2597763792 INFO System health check status: passed 2597763902 ERROR Requested resource not found 2597764422 INFO User admin logged out
Команда «sed».
Команда sed имеет преимущество перед grep благодаря дополнительным функциям обработки текста.
Ее синтаксис следующий:
$ sed [OPTION]... {script-only-if-no-other-script} [input_file]
Использование sed как grep.
Эквивалент команды grep для поиска и печати записей файла, связанных со строкой ERROR, выглядит следующим образом:
$ sed -n '/ERROR/ p' SysLog.txt 2597763777 ERROR User annonymus access attempt on protected resource without credentials 2597763902 ERROR Requested resource not found
Опция -n запрещает sed печатать каждую отсканированную строку.
Замена совпавшей строки.
Предположим, мы хотим заменить строку ERROR на строку CRITICAL в нашем текстовом файле, реализация команды sed будет выглядеть следующим образом:
$ sed 's/ERROR/CRITICAL/' SysLog.txt Timestamp Category Message 2597743202 INFO System Boot up started 2597743402 INFO Critical services boot up: Autorization 2597743502 INFO Successful system boot up 2597753502 INFO Userlist access request by user admin 2597763777 CRITICAL User annonymus access attempt on protected resource without credentials 2597763792 INFO System health check status: passed 2597763902 CRITICAL Requested resource not found 2597764422 INFO User admin logged out
Изменение файлов.
Использование флага -i вместе с определяемым пользователем суффиксом позволяет sed создать резервную копию входного файла перед применением постоянных изменений.
Например, мы можем переименовать строку CRITICAL обратно в ERROR только после создания резервной копии исходного состояния файла.
$ sed -ibackup 's/CRITICAL/ERROR/' SysLog.txt
Исходный файл будет переименован в резервную копию SysLog.txt.
$ ls -l SysLog.txtbackup -rw-r--r-- 1 user user 451 дек 25 09:21 SysLog.txtbackup
Мы также можем убедиться с помощью команды cat, что изменения файла произошли:
$ cat SysLog.txt Timestamp Category Message 2597743202 INFO System Boot up started 2597743402 INFO Critical services boot up: Autorization 2597743502 INFO Successful system boot up 2597753502 INFO Userlist access request by user admin 2597763777 ERROR User annonymus access attempt on protected resource without credentials 2597763792 INFO System health check status: passed 2597763902 ERROR Requested resource not found 2597764422 INFO User admin logged out
Ограничение изменений sed определенным номером строки.
Чтобы ограничить операции sed строкой номер 6 текстового файла, можно использовать следующую команду:
$ sed '6 s/ERROR/CRITICAL/' SysLog.txt Timestamp Category Message 2597743202 INFO System Boot up started 2597743402 INFO Critical services boot up: Autorization 2597743502 INFO Successful system boot up 2597753502 INFO Userlist access request by user admin 2597763777 CRITICAL User annonymus access attempt on protected resource without credentials 2597763792 INFO System health check status: passed 2597763902 ERROR Requested resource not found 2597764422 INFO User admin logged out
Для указания диапазона от 2 до 4, выполните:
$ sed '2,4 s/INFO/NOTE/' SysLog.txt Timestamp Category Message 2597743202 NOTE System Boot up started 2597743402 NOTE Critical services boot up: Autorization 2597743502 NOTE Successful system boot up 2597753502 INFO Userlist access request by user admin 2597763777 ERROR User annonymus access attempt on protected resource without credentials 2597763792 INFO System health check status: passed 2597763902 ERROR Requested resource not found 2597764422 INFO User admin logged out
Чтобы напечатать совпадения с шаблоном, начиная с определенной строки, например, строки 5, выполните:
$ sed -n '5,/INFO/ p' SysLog.txt 2597753502 INFO Userlist access request by user admin 2597763777 ERROR User annonymus access attempt on protected resource without credentials 2597763792 INFO System health check status: passed
Команда awk.
Команду awk можно использовать для выполнения операций со временем, арифметических операций и манипуляций со строками благодаря множеству встроенных функций. Кроме того, пользователям разрешено определять свои настраиваемые функции.
Синтаксис команды следующий:
awk [options] script file
Использование awk как grep
awk-эквивалент команды grep для поиска строки в файле выглядит следующим образом:
$ awk '/ERROR/{print $0}' SysLog.txt 2597763777 ERROR User annonymus access attempt on protected resource without credentials 2597763902 ERROR Requested resource not found
Замена совпадающей строки
Команда awk использует gsub (встроенный метод) для операций замены строк.
$ awk '{gsub(/ERROR/, "CRITICAL")}{print}' SysLog.txt Timestamp Category Message 2597743202 INFO System Boot up started 2597743402 INFO Critical services boot up: Autorization 2597743502 INFO Successful system boot up 2597753502 INFO Userlist access request by user admin 2597763777 CRITICAL User annonymus access attempt on protected resource without credentials 2597763792 INFO System health check status: passed 2597763902 CRITICAL Requested resource not found 2597764422 INFO User admin logged out
Добавление верхних и нижних колонтитулов.
Мы можем добавлять верхние и нижние колонтитулы во входные файлы, используя блоки BEGIN и END awk, как показано ниже:
$ awk 'BEGIN {print "SYS LOG SUMMARY\n--------------"} {print} END {print "--------------\nEND OF LOG SUMMARY"}' SysLog.txt SYS LOG SUMMARY -------------- Timestamp Category Message 2597743202 INFO System Boot up started 2597743402 INFO Critical services boot up: Autorization 2597743502 INFO Successful system boot up 2597753502 INFO Userlist access request by user admin 2597763777 ERROR User annonymus access attempt on protected resource without credentials 2597763792 INFO System health check status: passed 2597763902 ERROR Requested resource not found 2597764422 INFO User admin logged out -------------- END OF LOG SUMMARY
Манипуляции со столбцами.
Для таких документов, как файлы CSV состоящими из строк и столбцов, мы можем указать только определенные столбцы для вывода. Например, выведем 1-й и 2-й столбец нашего файла.
$ awk '{print $1, $2}' SysLog.txt Timestamp Category 2597743202 INFO 2597743402 INFO 2597743502 INFO 2597753502 INFO 2597763777 ERROR 2597763792 INFO 2597763902 ERROR 2597764422 INFO
Пользовательский разделитель полей.
По умолчанию, awk признает пробелы в качестве разделителей. Если в обрабатываемом тексте в качестве разделителей используются такие символы, как запятые или точки с запятой, вы можете указать их следующим образом:
$ awk -F "," '{print $1, $2}' SysLog.txt или $ awk -F ";" '{print $1 $2}' SysLog.txt
Арифметические операции
С помощью awk можно подсчитать количество появления определенных строк, следующим образом:
$ awk '{count[$2]++} END {print count["INFO"]}' SysLog.txt 6
Числовое сравнение.
Сценарий awk удобно интерпретирует значения как числа, а не просто как строку. Например, мы могли бы получить записи файлов с временными метками старше 2597763777 следующим образом:
$ awk '{ if ($1 > 2597763777) {print $0} }' SysLog.txt Timestamp Category Message 2597763792 INFO System health check status: passed 2597763902 ERROR Requested resource not found 2597764422 INFO User admin logged out
Заключение.
Теперь мы можем немного оценить сложность исплользования каждого из инструментов обработки текста. Для каждого случая, обычно используют ту команду, которая необходимо. Для себя, я сделал следующие выводы по использованию:
- Если просто ищу какой-либо текст, содержащийся в файле, то я использую команду grep.
- Если мне надо не просто найти текст, но и заменить его на другой в файле, то для этого я использую команду sed
- Если мне надо обработать текст, или использовать сложные сценарии для поиска и отображения текста, то я использую awk.
Надеюсь, вам эта статья помогла тоже определиться, что и в каком случае использовать.
Was this helpful?
1 / 0