Awk linux замена текста

Обновлено: 07.07.2024

Текст это сердце 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 обрабатывает одну строку за раз, вот этому подтверждение:

echo -e 'one 1\n two 2' | 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 один раз в получите очень мощный и полезный инструмент на всю жизнь.

Возникла необходимость изменения некоторых параметров в файле большого размера (дамп базы данных больше трех гигабайт). Редакторы отпадают (слишком тяжело им "ворочать" таким обьемом данных), но для интереса попробовал с помощью таких редакторов:

  • joe - выпадал в корку (не хватало места в /tmp, размером 2 GB)
  • mcedit - ругался при запуске, что "файл слишком большой"
  • ee - "немного задумавшись" открыл файл, довольно шустро работал с поиском. Но вот замены что-то не обнаружил (не юзаю я этот редактор, а разбираться как-то неохота)
  • vi - также "задумчиво" открыл файл. Замену произвел с помощью команды ":g/ old_text /s// new_text /g<ENTER>". Запись файла по команде ":wq" также заняла довольно продолжительное время. Но отработалось

Для решения подобной задачи все таки лучше использовать другие способы. Итак, исходные данные:

Заменим строку "laptops" на "servers" несколькими способами.

Способ 1. Замена подстроки в одном файле с помощью sed

Способ 2. Замена подстроки в одном файле с помощью perl

Способ 3. Замена подстроки с помощью awk

Теперь отсортируем выводы по ресурсоемкости операций (использовалась утилита time, замена использовалась для файла размером 2.3GB)

Способ 1

10.915u 9.029s 2:35.01 12.8% 37+1490k 14962+18828io 0pf+0w

Способ 2

7.445u 9.400s 2:52.98 9.7% 5+1503k 19574+18828io 0pf+0w

Способ 3

0.000u 0.077s 0:00.42 16.6% 154+1332k 9+0io 9pf+0w

Информация для размышлений предоставлена, а необходимый результат достигнут.

Как-то странно, обычно sed работает намного быстрее, чем awk и тем более perl. А результаты говорят обратное

У себя пробовали провести тестирование? Какие результаты?

У меня awk "урезает" исходный файл до 4097 байт!

Есть идеи по поводу причин такого странного поведения?

Favorite

Добавить в избранное

Главное меню » Linux » Как заменить строку в файле в Bash

Bash Heredoc

К ак программисту вам может потребоваться работать с разными типами файлов для временного или постоянного хранения данных. Иногда вам может потребоваться заменить часть файла или изменить конкретное содержимое файла. Чтобы заменить содержимое в файле, вы должны найти конкретную строку файла. Команда sed используется для замены любой строки в файле с помощью сценария bash. Эту команду можно использовать различными способами для замены содержимого файла в bash. Команда AWK также может быть использована для замены строки в файле. В этой статье показано, как заменить любое строковое значение из файла с помощью сценария bash. Для отображения операций замены создается текстовый файл с именем Sales.txt со следующим содержимым.

Заменить строку в файле командой `sed`

Каждая часть приведенного выше синтаксиса объясняется ниже.

search_string содержит строковое значение, которое будет искать в файле для замены.

replace_string содержит строковое значение, которое будет использоваться для замены содержимого файла, соответствующего значению search_string .

Пример 1: заменить файл командой sed

В следующем скрипте текст для поиска и замены будет взят у пользователя. Если строка поиска существует в Sales.txt, она будет заменена строкой замены. Здесь будет выполняться поиск с учетом регистра.

Пример 2: Замена файла командой sed с флагом g и i

Следующий сценарий будет работать так же, как и предыдущий пример, но в строке поиска будет производиться глобальный поиск флага «g», а поиск без учета регистра будет выполняться для флага «i».

Пример 3. Замена файла командой sed и шаблоном совпадающих цифр

Следующий сценарий выполнит поиск всего числового содержимого в файле и заменит содержимое, добавив символ «$» в начале чисел.

Заменить строку в файле командой awk

Пример 4: заменить файл командой awk

Следующий скрипт сохранит обновленное содержимое в файле temp.txt, который будет переименован в исходный файл.

Вывод

В этой статье показано, как использовать сценарии bash для замены определенных строк в файле. Задача по замене строки в файле станет для вас проще после отработки приведенных выше примеров.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.


Простой поиск с использованием grep:

Поиск и замена текста в файлах:

Удаление определенного символа из файлов

Нужно символы прописывать в уникоде, если правильно понял.

Как заменить слово в файлах при рекурсивном поиске Linux?

Этой строкой мы ищем во всех файлах с разрешением *.py от текущей директории строку text_1 и заменяя ее наtext_2, так же можно использовать regexp выражения.

Еще примеры

Для начала делаем поиск по фразе которая нам необходима, нам покажет все файлы и в каких строках содержится данная фраза:

или для конкретных файлов:

Выполнить замену можно еще следующим образом:

Допустим, Вам необходимо выполнить замену целой строки ( закомментировать какую либо функцию, добавив // перед самой функцией), то можно это сделать:

Экранируем спец символы и заменяем на любую другую строку, для этого:

Данная команда заменит одну строку на другую во всех файлах.

Упрощенная версия ее:

То чтобы удалить все строки кода между данными комментариями, выполните:

Я делал сканирование maldet и нашел много вредоносного кода, по этому, я удалил его так:

Как заменить всю строку на другую? Та вот так можно:

Или тоже самое, но через переменные:

-===Пример===-

Предположим, имеется файл и в нем находится:

Для этого, выполним:

PS: О долбанном SED-е я расскажу очень не скоро, он меня реально бесит и злит. Кто ее придумал, реальный сука ДЖЕДАЙ 😀

Делаю замену версий в Terraform так:

Делаем замену другим способом:

ПРИМЕЧАНИЕ! Утилиту rpl необходимо установить.

Я попозже постараюсь привести еще примеров и рассказать о утилите в своей новой статье.

Когда не удобно искать файлы в консольном режиме и есть GUI интерфейс, то можно воспользоваться утилитой regexxer.
Debian/Ubuntu/Mint:

CentOS/RedHat/Fedora:

Очень простая и хорошая утилита, я сам ею пользовался и тестировал на своей виртуальной машине на Debian.

Читайте также: