Како да го користите јазикот AWK за манипулирање со текст во Linux


Вовед

Услужните програми за Linux често ја следат филозофијата на дизајнот на Unix. Алатките се охрабруваат да бидат мали, да користат обични текстуални датотеки за внесување и излез и да работат на модуларен начин. Поради ова наследство, имаме одлична функционалност за обработка на текст со алатки како sed и awk.

awk е и програмски јазик и текстуален процесор што можете да го користите за манипулирање со текстуални податоци на многу корисни начини. Во ова упатство, ќе истражите како да ја користите алатката за командна линија awk и како да ја користите за обработка на текст.

Основна синтакса

Командата awk е стандардно вклучена во сите модерни системи на Linux, така што не треба да ја инсталирате за да започнете да ја користите.

awk е најкорисен при ракување со текстуални датотеки што се форматирани на предвидлив начин. На пример, тој е одличен во парсирање и манипулирање со табеларни податоци. Работи на линија по линија и се повторува низ целата датотека.

Стандардно, користи празно место (простори, јазичиња, итн.) за да ги одвои полињата. За среќа, многу конфигурациски датотеки на вашиот Linux систем го користат овој формат.

Основниот формат на командата awk е:

  1. awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse

Можете да го изоставите или делот за пребарување или делот за акција од која било команда awk. Стандардно, дејството што се презема ако делот „акција“ не е даден е „печатење“. Ова едноставно ги печати сите линии што се совпаѓаат.

Ако делот за пребарување не е даден, awk го извршува дејството наведено на секоја линија.

Ако се дадени и двете, awk го користи делот за пребарување за да одлучи дали тековната линија ја одразува шемата, а потоа ги извршува дејствата на совпаѓањата.

Во својата наједноставна форма, можете да го користите awk како cat за да ги испечатите сите линии од текстуална датотека на екранот.

Направете датотека favorite_food.txt во која се наведени омилените јадења на група пријатели:

  1. echo "carrot sandy
  2. wasabi luke
  3. sandwich brian
  4. salad ryan
  5. spaghetti jessica" > favorite_food.txt

Сега користете ја командата awk за да ја испечатите датотеката на екранот:

  1. awk '{print}' favorite_food.txt

Ќе ја видите датотеката отпечатена на екранот:

Output
carrot sandy wasabi luke sandwich brian salad ryan spaghetti jessica

Ова не е многу корисно. Ајде да ги испробаме можностите за филтрирање на пребарувањето на awk со пребарување низ датотеката за текстот \sand:

  1. awk '/sand/' favorite_food.txt
Output
carrot sandy sandwich brian

Како што можете да видите, awk сега ги печати само линиите што ги имаат знаците „sand“ во нив.

Користејќи редовни изрази, можете да наведете одредени делови од текстот. За да се прикаже само линијата што започнува со буквите \песок, користете го регуларниот израз ^sand:

  1. awk '/^sand/' favorite_food.txt

Овој пат се прикажува само една линија:

Output
sandwich brian

Слично на тоа, можете да го користите делот за акција за да одредите кои делови од информации сакате да ги испечатите. На пример, за да ја испечатите само првата колона, користете ја следнава команда:

  1. awk '/^sand/ {print $1;}' favorite_food.txt
Output
sandwich

Можете да ја упатувате секоја колона (ограничена со празно место) со променливи поврзани со нивниот број на колона. На пример, првата колона е $1, втората е $2 и можете да ја повикате целата линија со $0.

Внатрешни променливи и проширен формат

Командата awk користи некои внатрешни променливи за доделување одредени информации додека обработува датотека.

Внатрешните променливи што ги користи awk се:

  • FILENAME: упатува на тековната влезна датотека.
  • FNR: Го упатува бројот на тековниот запис во однос на тековната влезна датотека. На пример, ако имате две влезни датотеки, ова ќе ви го каже рекордниот број на секоја датотека наместо вкупниот број.
  • FS: Тековниот раздвојувач на полиња што се користи за означување на секое поле во записот. Стандардно, ова е поставено на празно место.
  • NF: Бројот на полиња во тековниот запис.
  • NR: Бројот на тековниот рекорд.
  • OFS: сепаратор на поле за излезните податоци. Стандардно, ова е поставено на празно место.
  • ORS: сепаратор на записи за излезените податоци. Стандардно, ова е знак за нова линија.
  • RS: сепаратор на записи што се користи за разликување на одделни записи во влезната датотека. Стандардно, ова е знак за нова линија.

Можете да ги менувате вредностите на овие променливи по желба за да одговараат на потребите на вашите датотеки. Обично тоа го правите за време на фазата на иницијализација на вашата обработка.

Ова нè доведува до друг важен концепт. Синтаксата awk е малку посложена од онаа што сте ја користеле досега. Исто така, постојат опционални блокови BEGIN и END кои можат да содржат команди за извршување пред и по обработката на датотеката, соодветно.

Ова ја прави нашата проширена синтакса да изгледа вака:

  1. awk 'BEGIN { action; }
  2. /search/ { action; }
  3. END { action; }' input_file

Клучните зборови BEGIN и END се специфични групи на услови, исто како и параметрите за пребарување. Тие се совпаѓаат пред и откако документот е обработен.

Ова значи дека можете да промените некои од внатрешните променливи во делот BEGIN. На пример, датотеката /etc/passwd е разграничена со две точки (:) наместо празно место.

За да ја испечатите првата колона од оваа датотека, извршете ја следнава команда:

  1. awk 'BEGIN { FS=":"; }
  2. { print $1; }' /etc/passwd
Output
root daemon bin sys sync games man . . .

Можете да ги користите блоковите BEGIN и END за да печатите информации за полињата што ги печатите. Користете ја следнава команда за да ги трансформирате податоците од датотеката во табела, убаво распоредени со јазичиња користејќи \t:

  1. awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
  2. {print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
  3. END { print "---------\nFile Complete" }' /etc/passwd

Ќе го видите овој излез:

Output
User UID GID Home Shell -------------- root 0 0 /root /bin/bash daemon 1 1 /usr/sbin /bin/sh bin 2 2 /bin /bin/sh sys 3 3 /dev /bin/sh sync 4 65534 /bin /bin/sync . . . --------- File Complete

Како што можете да видите, можете многу убаво да ги форматирате работите со искористување на некои од функциите на awk.

Секој од проширените делови е опционален. Всушност, самиот дел од главната акција е опционален доколку се дефинира друг дел. На пример, можете да правите работи како ова:

  1. awk 'BEGIN { print "We can use awk like the echo command"; }'

И ќе го видите овој излез:

Output
We can use awk like the echo command

Сега ајде да погледнеме како да бараме текст во полињата на излезот.

Пребарување на терен и сложени изрази

Во еден од претходните примери, ја испечативте линијата во датотеката favorite_food.txt што започнуваше со \sand. Ова беше лесно бидејќи го баравте почетокот на целата линија.

Што ако сакате да дознаете дали шемата за пребарување се совпаѓа на почетокот на поле?

Направете нова верзија на датотеката favorite_food.txt која додава број на ставка пред храната на секое лице:

  1. echo "1 carrot sandy
  2. 2 wasabi luke
  3. 3 sandwich brian
  4. 4 salad ryan
  5. 5 spaghetti jessica" > favorite_food.txt

Ако сакате да ги најдете сите намирници од оваа датотека што почнуваат со \sa, можете да започнете со пробување на нешто како ова:

  1. awk '/sa/' favorite_food.txt

Ова ги прикажува сите линии што содржат \sa:

Output
1 carrot sandy 2 wasabi luke 3 sandwich brian 4 salad ryan

Овде, одговарате на кој било пример на \sa во зборот. Ова завршува вклучувајќи работи како \wasabi што ја има шемата во средината или \песочна што не е во колоната што ја сакате. Во ова случај да ве интересираат само зборовите почнуваат со \sa“ во колоната втора.

Можете да му кажете на awk да одговара само на почетокот на втората колона со користење на оваа команда:

  1. awk '$2 ~ /^sa/' favorite_food.txt

Како што можете да видите, ова ни овозможува да бараме натпревар само на почетокот на втората колона.

Делот field_num ~ одредува дека awk треба да внимава само на втората колона.

Output
3 sandwich brian 4 salad ryan

Можете исто толку лесно да пребарувате работи што не се совпаѓаат со вклучување на \!“ знак пред тилдата (~). Оваа команда ќе ги врати сите линии што не имаат храна што започнува со \sa”:

  1. awk '$2 !~ /^sa/' favorite_food.txt
Output
1 carrot sandy 2 wasabi luke 5 spaghetti jessica

Ако подоцна одлучите дека ве интересираат само линиите што не започнуваат со \sa и бројот на ставката е помал од 5, можете да користите сложен израз како овој:

  1. awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt

Ова воведува неколку нови концепти. Првата е способноста да се додадат дополнителни барања за линијата да се совпаѓа со користење на операторот &&. Користејќи го ова, можете да комбинирате произволен број услови за да се совпадне линијата. Во овој случај, го користите овој оператор за да додадете проверка дека вредноста на првата колона е помала од 5.

Ќе го видите овој излез:

Output
1 carrot sandy 2 wasabi luke

Можете да користите awk за обработка на датотеки, но можете да работите и со излезот од други програми.

Обработка на излез од други програми

Можете да ја користите командата awk за да го анализирате излезот од други програми наместо да одредувате име на датотека. На пример, можете да користите awk за да ја анализирате IPv4 адресата од командата ip.

Командата ip a ја прикажува IP адресата, адресата за емитување и други информации за сите мрежни интерфејси на вашиот уред. За да ги прикажете информациите за интерфејсот наречен eth0, користете ја оваа команда:

  1. ip a s eth0

Ќе ги видите следните резултати:

Output
2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever

Можете да користите awk за да ја насочите линијата inet и потоа да ја испечатите само IP адресата:

  1. ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'

Знамето -F му кажува на awk да се ограничи со напредни коси или празни места користејќи го регуларниот израз [\/ ]+. Ова ја дели линијата inet 172.17.0.11/16 во посебни полиња. IP-адресата е во третото поле бидејќи празнините на почетокот на линијата исто така се бројат како поле, бидејќи сте разграничени со празни места, како и со коси. Забележете дека awk ги третираше последователните празни места како единствен простор во овој случај.

Излезот ја покажува IP адресата:

Output
172.17.0.11

Ќе најдете многу места каде што можете да користите awk за пребарување или анализирање на излезот од други команди.

Заклучок

Досега треба да имате основно разбирање за тоа како можете да ја користите командата awk за манипулирање, форматирање и селективно печатење текстуални датотеки и текови на текст. Сепак, Awk е многу поголема тема и всушност е цел програмски јазик полн со доделување променливи, контролни структури, вградени функции и многу повеќе. Можете да го користите во вашите сопствени скрипти за да го форматирате текстот на сигурен начин.

За да дознаете повеќе за awk, можете да ја прочитате бесплатната книга од јавен домен од нејзините создавачи, која навлегува во многу повеќе детали.