The OpenNET Project / Index page

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

Примеры использования Awk
Использование сокращений.

Конструкцию, используемую для вывода строк соответствующих заданной маске:
   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}'
 
27.10.2008 , Источник: http://www.catonmat.net/blog/ten-aw...
Ключи: awk, shell / Лицензия: CC-BY
Раздел:    Корень / Программисту и web-разработчику / Shell / Готовые скрипты

Обсуждение [ Линейный режим | Показать все | RSS ]
  • 1.1, Queeq (?), 14:35, 27/10/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Супер, спасибо!
     
  • 1.2, rrv (??), 19:05, 27/10/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Вот кому интересно еще подборочка рецептов awk: http://rrv.nsk.ru/wiki/index.php/Awk_-_%D1%80%D0%B5%
     
  • 1.3, Hubbitus (ok), 14:27, 28/10/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Крайне полезно, однозначно обе ссылки в закладке.

    В статье только крайне удручают кавычки в виде & #8217; :(

     
  • 1.4, Kreept (??), 11:18, 21/11/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Спасибо! Очень интересная статейка.  
     
  • 1.5, Дмитрий Б. (?), 00:15, 07/04/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Прошу подсказать, как вывести все столбцы начиная с 7-го и более. т.е. если их может быть бесконечно.

    пример:

    -rw-r--r-- 3 dmio   46 23 23:34 1
    -rw-r--r-- 1 dmio    0 11 23:33 78
    -rw-r--r-- 1 dmio    88 84 23:41 1 1 1 1

    нужно вывести
    1
    78
    1 1 1 1

    подскажите как?

     
     
  • 2.6, Hubbitus (ok), 13:18, 10/04/2010 [^] [^^] [^^^] [ответить]  
  • +/
    >нужно вывести
    >1
    >78
    >1 1 1 1
    >
    >подскажите как?

    Ну если именно с помощью awk надо, то можно как-то так:
    awk '{ for (i=7;i<=NF;i++) printf $i FS; print ""}'

     

  • 1.7, user (??), 23:34, 04/11/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Здравствуйте! Подскажите пожалуйста, как вывести для каждого из файлов отчёт вида: всего в магазине … продано товаров на сумму … рублей. // при помощи команды - awk
     
     
  • 2.8, Hubbitus (ok), 03:20, 05/11/2010 [^] [^^] [^^^] [ответить]  
  • +/
    > Здравствуйте! Подскажите пожалуйста, как вывести для каждого из файлов отчёт вида: всего
    > в магазине … продано товаров на сумму … рублей. // при
    > помощи команды - awk

    Для какого файла-то?? Какая структура?

     

  • 1.9, Demeo (?), 21:02, 14/12/2010 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    А можно ли сортировать вывод по алфавиту?
    При выводе командой ifstat -W 1 1 статистики с множества интерфейсов шапка оказывается отдельно от данных, но строки помечены буквой англ. алфавита.
     
     
  • 2.10, Hubbitus (ok), 14:52, 15/12/2010 [^] [^^] [^^^] [ответить]  
  • +/
    > А можно ли сортировать вывод по алфавиту?
    > При выводе командой ifstat -W 1 1 статистики с множества интерфейсов шапка
    > оказывается отдельно от данных, но строки помечены буквой англ. алфавита.

    Да можно конечно сортировать, команда sort Вам в помощь. Только как это к AWK-то относится??

     

  • 1.11, uri (??), 18:26, 23/02/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    <q>Вывести группу строк, начиная со строки, в которой есть foo, и заканчивая
    строкой, в которой есть bar:
       awk '/foo/,/bar/'

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

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

    "Более оптимальные вариант не работает"

    $ cat test
    0
    1
    2
    3
    4
    5
    6

    $cat test|awk '/1/,/5/'
    1
    2
    3
    4
    5

    $ cat test|awk '/1/{p=0};p;/5/{p=1}'
    6

     
  • 1.12, Анон (?), 14:36, 28/10/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    >Например, чтобы показать из файла с текстом только текст, отмеченный как =текст=
    >
    >можно использовать:
    >   awk -v RS='=' '!(NR%2)'
    >
    >с форматированием переносов строк:
    >
    >   awk -v RS='=' '!(NR%2){gsub(/\n/," ");print}'

    А !(NR%2) здесь зачем? Либо дополните описание, либо уберите лишний функционал.

     
  • 1.13, Андрей (??), 18:54, 10/05/2012 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Есть файл May 9 21 58 56 kernel OUTPUT CentOS IN OUT br0 SRC 192 168 0 1 DST... текст свёрнут, показать
     
     
  • 2.14, AstraSerg (??), 22:07, 15/06/2012 [^] [^^] [^^^] [ответить]  
  • +/
    >[оверквотинг удален]
    > 16 столбце.
    > Нужно что-то типа
    > 1 PROTO=TCP
    > 3 PROTO=UDP
    > 4 PROTO=UDP
    > 5 PROTO=TCP
    > 6 PROTO=TCP
    > 7 PROTO=TCP
    > 8 PROTO=TCP
    > 10 PROTO=UDP

    awk -F'PROTO=' '{print $2}' | awk '{print "PROTO="$1}'

     

  • 1.15, bzmn (?), 18:10, 01/09/2012 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    а вывести только те строки, определенный столб которых содержит математическое значение равное/неравное/меньше/больше/мИЛИр/бИЛИр заданному значению?
     
     
  • 2.16, bzmn (?), 21:07, 27/09/2012 [^] [^^] [^^^] [ответить]  
  • +/
    сам спросил - сам отвечаю:

    awk ' $1 >= 0 '

     

  • 1.17, ram (??), 17:38, 30/11/2012 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    подскажите, как вывести только слова, обособленные к примеру скобками?

    из такого:

    [tekila]trololo[-borjomi]
    [tort]tralala[-pizza]

    получить:

    trololo
    tralala

     
     
  • 2.18, anon_ddqd (?), 15:57, 25/10/2013 [^] [^^] [^^^] [ответить]  
  • +/
    bash-3.2$  less test.txt
    [tekila]trololo[-borjomi]
    [tort]tralala[-pizza]
    bash-3.2$ less test.txt | awk -F"]" '{print $2}' | awk -F"[" '{print $1}'
    trololo
    tralala
    bash-3.2$
     

  • 1.19, Кирилл (??), 11:59, 21/11/2013 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Здравствуйте.

    Есть файл с содержимым типа:
    a = b
    b = c
    a = b
    a = b
    a = b
    b = c
    a = b

    и т.д

    Как вывести только те a = b после которых идет b = c?

     
  • 1.20, palit (ok), 18:39, 25/12/2013 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Добрый день !!!
    подскажите как можно заменить определенное количество полей(колонок) в строке файла ?
    есть файл вырезаю 4 поля с помощью awk и нужно вставить эти 4 поля в другой файл
    #!/bin/bash
    f1=addcron.txt
    f2=file.txt
    res='awk '/#1/ {print $1, $2, $3, $4}' f1'  #вырезание 4 полей в одном файле
    пробую вставить в другой файл заменяется только одно поле

    awk '{sub ($1, "'"$res"'"); print}' $f2 #вставка 4 полей в другой файл
    как можно заменить 4 поля в определенной строке или, написать скрипт в одной строке с помощью sed или awk

    содержимое файла f1 addcron.txt
    22 33 6 5      #1
    192.168.2.1
    содержимое файля f2 file.txt
    /1 22 4 * root   /home/creattar.sh

     
  • 1.21, Yura (??), 09:50, 18/08/2017 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Здравствуйте.
    Есть файл  типа
    Username: Александр
      ROLE_USER
      ROLE_ADMIN
      ROLE_SUPER_ADMIN
      ROLE_SUPPORT_CHAT
      ROLE_TAG_EDITOR
      ROLE_TEST

    Username: Александр
      ROLE_USER
      ROLE_ADMIN
      ROLE_SUPER_ADMIN
      ROLE_SUPPORT_CHAT
      ROLE_TAG_EDITOR
      ROLE_TEST2

    Username: Rus10Neo
      ROLE_USER
      ROLE_SONATA_EDITOR
      ROLE_SONATA_READER
      ROLE_SONATA_ADMIN
      ROLE_FOOTBALL_PLAYER_MERGE
      ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_STAFF
      ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_BET_LINK_EDITOR
      ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_EDITOR
      ROLE_ALL_TIPS_EDITOR
      ROLE_INTELL_ADMIN_ADMIN_FOOTBALL_MEETING_TV_CHANNEL_ADMIN
      ROLE_TIP_LOCALE_ADMIN

    Username: Rus10Neo
      ROLE_USER
      ROLE_SONATA_EDITOR
      ROLE_SONATA_READER
      ROLE_SONATA_ADMIN
      ROLE_FOOTBALL_PLAYER_MERGE
      ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_STAFF
      ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_BET_LINK_EDITOR
      ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_EDITOR
      ROLE_ALL_TIPS_EDITOR
      ROLE_INTELL_ADMIN_ADMIN_FOOTBALL_MEETING_TV_CHANNEL_ADMIN
      ROLE_TIP_LOCALE_ADMIN
      ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_BET_LINK_ADMIN
      ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_ADMIN

    нужно разбить на абзацы. количество строк динамическое и количество абзацев. Заранее благодарен

     
     
  • 2.22, Dima (??), 12:30, 18/08/2017 [^] [^^] [^^^] [ответить]  
  • +/
    >[оверквотинг удален]
    >   ROLE_FOOTBALL_PLAYER_MERGE
    >   ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_STAFF
    >   ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_BET_LINK_EDITOR
    >   ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_EDITOR
    >   ROLE_ALL_TIPS_EDITOR
    >   ROLE_INTELL_ADMIN_ADMIN_FOOTBALL_MEETING_TV_CHANNEL_ADMIN
    >   ROLE_TIP_LOCALE_ADMIN
    >   ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_BET_LINK_ADMIN
    >   ROLE_INTELL_ADMIN_ADMIN_IN_FORECAST_ADMIN
    > нужно разбить на абзацы. количество строк динамическое и количество абзацев. Заранее благодарен

    Можно образец, как должен выглядеть результат?
    Из описания не очень понятно.

     

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Спонсоры:
    Слёрм
    Inferno Solutions
    Hosting by Ihor
    Хостинг:

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