The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"Раздел полезных советов: Примеры использования Awk"
Отправлено auto_tips, 27-Окт-08 14:35 
Использование сокращений.

Конструкцию, используемую для вывода строк соответствующих заданной маске:
   awk '{if ($0 ~ /pattern/) print $0}'

можно сократить до
   awk '/pattern/'

Условие в awk может быть задано вне скобок, т.е. получаем:
   awk '$0 ~ /pattern/ {print $0}'

По умолчанию, действия производится со всей строкой, $0 можно не указывать:
   awk '/pattern/ {print}'

print - является действием по умолчанию, его тоже можно не указывать.
   awk '/pattern/'

Для вывода значения первого столбца строки в которой присутствует маска LEGO:
   awk '/LEGO/ {print $1}'

Для вывода значения первого столбца строки во втором столбце которой присутствует маска LEGO:
   awk '$2 ~ /LEGO/ {print $1}'

Для замены слова LIGO на LEGO и вывода только измененных строк можно использовать:
   awk '{if(sub(/LIGO/,"LEGO")){print}}'

Но есть выводить нужно все строки (как sed ’s/LIGO/LEGO/’), конструкцию можно упростить
(1 - true для всех строк):
   awk '{sub(/LIGO/,"LEGO")}1'

Вывести все строки, за исключением каждой шестой:
   awk 'NR % 6'

Вывести строки начиная с 6 (как tail -n +6 или sed '1,5d'):
   awk 'NR > 5'

Вывести строки в которых значение второго столбца равно foo:
   awk '$2 == "foo"'

Вывести строки, в которых 6 и более столбцов:
   awk 'NF >= 6'

Вывести строки в которых есть слова foo и bar:
   awk '/foo/ && /bar/'

Вывести строки в которых есть слово foo, но нет bar:
   awk '/foo/ && !/bar/'

Вывести строки в которых есть слова foo или bar (как grep -e 'foo' -e 'bar'):
   awk '/foo/ || /bar/'

Вывести все непустые строки:
   awk 'NF'

Вывести все строки, удалив содержимое последнего столбца:
   awk 'NF--'

Вывести номера строк перед содержимым:
   awk '$0 = NR" "$0'

Заменим команды (пропускаем 1 строку, фильтруем строки с foo и заменяем foo на bar,
затем переводим в верхний регистр и выводим значение второго столбца)
   cat test.txt | head -n +1 | grep foo | sed 's/foo/bar/' | tr '[a-z]' '[A-Z]' | cut -d ' ' -f 2

аналогичной конструкцией на awk:
   cat test.txt | awk 'NR>1 && /foo/{sub(/foo/,"bar"); print toupper($2)}'


Использование диапазонов.

Вывести группу строк начиная со строки в которой есть foo и заканчивая строкой в которой есть bar:
   awk '/foo/,/bar/'

Исключив из вывода строки с вхождением заданных масок:
   awk '/foo/,/bar/{if (!/foo/ && !/bar/)print}'

Более оптимальные вариант:
   awk '/bar/{p=0};p;/foo/{p=1}'

Исключить только строку с завершающим вхождением (bar)
   awk '/bar/{p=0} /foo/{p=1} p'

Исключить только строку с начальным вхождением (foo)
   awk 'p; /bar/{p=0} /foo/{p=1}'


Разбиение файла по шаблонам.

Имеется файл (file) в котором группы строк разделены шаблонами FOO1,FOO2 и т.д.
Необходимо записать данные, находящиеся между метками FOO в разные файлы,
соответствующие указанным в FOO номерам.
   awk -v n=1 '/^FOO[0-9]*/{close("out"n);n++;next} {print > "out"n}' file

В GNU Awk можно сделать так:
   LC_ALL=C gawk -v RS='FOO[0-9]*\n' -v ORS= '{print > "out"NR}' file


Парсинг CSV.

По умолчанию, в качестве разделителя используется пробел и табуляция.
Чтобы определить иной разделитель, например запятую, нужно использовать FS=’,’ или опцию "-F"
в качестве параметра может быть задано регулярное выражение, например, FS=’^ *| *, *| *$’
Но для разбора CSV это не подойдет, так как пробелы могут присутствовать и внутри трок,
поэтому проще вырезать лидирующие пробелы перед и после запятой:

   FS=','
   for(i=1;i<=NF;i++){
     gsub(/^ *| *$/,"",$i);
     print "Field " i " is " $i;
   }

Если в CSV данные помещены в кавычки, например "field1","field2", то подойдет такой скрипт:

   FS=','
   for(i=1;i<=NF;i++){
     gsub(/^ *"|" *$/,"",$i);
     print "Field " i " is " $i;
   }

Но скрипт придется усовершенствовать для разбора полей вида:

field1, "field2,with,commas"  ,  field3  ,  "field4,foo"

   $0=$0",";  
   while($0) {
     match($0,/[^,]*,| *"[^"]*" *,/);
     sf=f=substr($0,RSTART,RLENGTH);
     gsub(/^ *"?|"? *,$/,"",f);
     print "Field " ++c " is " f;
     sub(sf,"");
   }


Проверка IPv4 адреса.

   awk -F '[.]' 'function ok(n) {
     return (n ~ /^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/)
   }
   {exit (ok($1) && ok($2) && ok($3) && ok($4))}'


Сравнение двух файлов.

Вывод всех дублирующихся строк из двух неотсортированных файлах file1 и file2:
   awk '!($0 in a) {c++;a[$0]} END {exit(c==NR/2?0:1)}' file1 file2


Вывод только выделенных блоков текста.
Например, чтобы показать из файла с текстом только текст отмеченный как =текст=
можно использовать:
   awk -v RS='=' '!(NR%2)'

с форматированием переносов строк:
   awk -v RS='=' '!(NR%2){gsub(/\n/," ");print}'


URL: http://www.catonmat.net/blog/ten-awk-tips-tricks-and-pitfalls/
Обсуждается: http://www.opennet.ru/tips/info/1811.shtml

 

Ваше сообщение
Имя*:
EMail:
Для отправки ответов на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру