Како да го користите јазикот AWK за манипулирање со текст во Linux
Вовед
Услужните програми за Linux често ја следат филозофијата на дизајнот на Unix. Алатките се охрабруваат да бидат мали, да користат обични текстуални датотеки за внесување и излез и да работат на модуларен начин. Поради ова наследство, имаме одлична функционалност за обработка на текст со алатки како sed и awk
.
awk
е и програмски јазик и текстуален процесор што можете да го користите за манипулирање со текстуални податоци на многу корисни начини. Во ова упатство, ќе истражите како да ја користите алатката за командна линија awk
и како да ја користите за обработка на текст.
Основна синтакса
Командата awk
е стандардно вклучена во сите модерни системи на Linux, така што не треба да ја инсталирате за да започнете да ја користите.
awk
е најкорисен при ракување со текстуални датотеки што се форматирани на предвидлив начин. На пример, тој е одличен во парсирање и манипулирање со табеларни податоци. Работи на линија по линија и се повторува низ целата датотека.
Стандардно, користи празно место (простори, јазичиња, итн.) за да ги одвои полињата. За среќа, многу конфигурациски датотеки на вашиот Linux систем го користат овој формат.
Основниот формат на командата awk
е:
- awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse
Можете да го изоставите или делот за пребарување или делот за акција од која било команда awk
. Стандардно, дејството што се презема ако делот „акција“ не е даден е „печатење“. Ова едноставно ги печати сите линии што се совпаѓаат.
Ако делот за пребарување не е даден, awk
го извршува дејството наведено на секоја линија.
Ако се дадени и двете, awk
го користи делот за пребарување за да одлучи дали тековната линија ја одразува шемата, а потоа ги извршува дејствата на совпаѓањата.
Во својата наједноставна форма, можете да го користите awk
како cat
за да ги испечатите сите линии од текстуална датотека на екранот.
Направете датотека favorite_food.txt
во која се наведени омилените јадења на група пријатели:
- echo "carrot sandy
- wasabi luke
- sandwich brian
- salad ryan
- spaghetti jessica" > favorite_food.txt
Сега користете ја командата awk
за да ја испечатите датотеката на екранот:
- awk '{print}' favorite_food.txt
Ќе ја видите датотеката отпечатена на екранот:
Outputcarrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica
Ова не е многу корисно. Ајде да ги испробаме можностите за филтрирање на пребарувањето на awk
со пребарување низ датотеката за текстот \sand:
- awk '/sand/' favorite_food.txt
Outputcarrot sandy
sandwich brian
Како што можете да видите, awk
сега ги печати само линиите што ги имаат знаците „sand“ во нив.
Користејќи редовни изрази, можете да наведете одредени делови од текстот. За да се прикаже само линијата што започнува со буквите \песок, користете го регуларниот израз ^sand
:
- awk '/^sand/' favorite_food.txt
Овој пат се прикажува само една линија:
Outputsandwich brian
Слично на тоа, можете да го користите делот за акција за да одредите кои делови од информации сакате да ги испечатите. На пример, за да ја испечатите само првата колона, користете ја следнава команда:
- awk '/^sand/ {print $1;}' favorite_food.txt
Outputsandwich
Можете да ја упатувате секоја колона (ограничена со празно место) со променливи поврзани со нивниот број на колона. На пример, првата колона е $1
, втората е $2
и можете да ја повикате целата линија со $0
.
Внатрешни променливи и проширен формат
Командата awk
користи некои внатрешни променливи за доделување одредени информации додека обработува датотека.
Внатрешните променливи што ги користи awk
се:
- FILENAME: упатува на тековната влезна датотека.
- FNR: Го упатува бројот на тековниот запис во однос на тековната влезна датотека. На пример, ако имате две влезни датотеки, ова ќе ви го каже рекордниот број на секоја датотека наместо вкупниот број.
- FS: Тековниот раздвојувач на полиња што се користи за означување на секое поле во записот. Стандардно, ова е поставено на празно место.
- NF: Бројот на полиња во тековниот запис.
- NR: Бројот на тековниот рекорд.
- OFS: сепаратор на поле за излезните податоци. Стандардно, ова е поставено на празно место.
- ORS: сепаратор на записи за излезените податоци. Стандардно, ова е знак за нова линија.
- RS: сепаратор на записи што се користи за разликување на одделни записи во влезната датотека. Стандардно, ова е знак за нова линија.
Можете да ги менувате вредностите на овие променливи по желба за да одговараат на потребите на вашите датотеки. Обично тоа го правите за време на фазата на иницијализација на вашата обработка.
Ова нè доведува до друг важен концепт. Синтаксата awk
е малку посложена од онаа што сте ја користеле досега. Исто така, постојат опционални блокови BEGIN
и END
кои можат да содржат команди за извршување пред и по обработката на датотеката, соодветно.
Ова ја прави нашата проширена синтакса да изгледа вака:
- awk 'BEGIN { action; }
- /search/ { action; }
- END { action; }' input_file
Клучните зборови BEGIN
и END
се специфични групи на услови, исто како и параметрите за пребарување. Тие се совпаѓаат пред и откако документот е обработен.
Ова значи дека можете да промените некои од внатрешните променливи во делот BEGIN
. На пример, датотеката /etc/passwd
е разграничена со две точки (:
) наместо празно место.
За да ја испечатите првата колона од оваа датотека, извршете ја следнава команда:
- awk 'BEGIN { FS=":"; }
- { print $1; }' /etc/passwd
Outputroot
daemon
bin
sys
sync
games
man
. . .
Можете да ги користите блоковите BEGIN
и END
за да печатите информации за полињата што ги печатите. Користете ја следнава команда за да ги трансформирате податоците од датотеката во табела, убаво распоредени со јазичиња користејќи \t
:
- awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
- {print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
- END { print "---------\nFile Complete" }' /etc/passwd
Ќе го видите овој излез:
OutputUser 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
.
Секој од проширените делови е опционален. Всушност, самиот дел од главната акција е опционален доколку се дефинира друг дел. На пример, можете да правите работи како ова:
- awk 'BEGIN { print "We can use awk like the echo command"; }'
И ќе го видите овој излез:
OutputWe can use awk like the echo command
Сега ајде да погледнеме како да бараме текст во полињата на излезот.
Пребарување на терен и сложени изрази
Во еден од претходните примери, ја испечативте линијата во датотеката favorite_food.txt
што започнуваше со \sand. Ова беше лесно бидејќи го баравте почетокот на целата линија.
Што ако сакате да дознаете дали шемата за пребарување се совпаѓа на почетокот на поле?
Направете нова верзија на датотеката favorite_food.txt
која додава број на ставка пред храната на секое лице:
- echo "1 carrot sandy
- 2 wasabi luke
- 3 sandwich brian
- 4 salad ryan
- 5 spaghetti jessica" > favorite_food.txt
Ако сакате да ги најдете сите намирници од оваа датотека што почнуваат со \sa, можете да започнете со пробување на нешто како ова:
- awk '/sa/' favorite_food.txt
Ова ги прикажува сите линии што содржат \sa:
Output1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan
Овде, одговарате на кој било пример на \sa во зборот. Ова завршува вклучувајќи работи како \wasabi што ја има шемата во средината или \песочна што не е во колоната што ја сакате. Во ова случај да ве интересираат само зборовите почнуваат со \sa“ во колоната втора.
Можете да му кажете на awk
да одговара само на почетокот на втората колона со користење на оваа команда:
- awk '$2 ~ /^sa/' favorite_food.txt
Како што можете да видите, ова ни овозможува да бараме натпревар само на почетокот на втората колона.
Делот field_num ~
одредува дека awk
треба да внимава само на втората колона.
Output3 sandwich brian
4 salad ryan
Можете исто толку лесно да пребарувате работи што не се совпаѓаат со вклучување на \!“ знак пред тилдата (~). Оваа команда ќе ги врати сите линии што не имаат храна што започнува со \sa”:
- awk '$2 !~ /^sa/' favorite_food.txt
Output1 carrot sandy
2 wasabi luke
5 spaghetti jessica
Ако подоцна одлучите дека ве интересираат само линиите што не започнуваат со \sa и бројот на ставката е помал од 5, можете да користите сложен израз како овој:
- awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt
Ова воведува неколку нови концепти. Првата е способноста да се додадат дополнителни барања за линијата да се совпаѓа со користење на операторот &&
. Користејќи го ова, можете да комбинирате произволен број услови за да се совпадне линијата. Во овој случај, го користите овој оператор за да додадете проверка дека вредноста на првата колона е помала од 5.
Ќе го видите овој излез:
Output1 carrot sandy
2 wasabi luke
Можете да користите awk
за обработка на датотеки, но можете да работите и со излезот од други програми.
Обработка на излез од други програми
Можете да ја користите командата awk
за да го анализирате излезот од други програми наместо да одредувате име на датотека. На пример, можете да користите awk
за да ја анализирате IPv4 адресата од командата ip
.
Командата ip a
ја прикажува IP адресата, адресата за емитување и други информации за сите мрежни интерфејси на вашиот уред. За да ги прикажете информациите за интерфејсот наречен eth0
, користете ја оваа команда:
- ip a s eth0
Ќе ги видите следните резултати:
Output2571: 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 адресата:
- ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'
Знамето -F
му кажува на awk
да се ограничи со напредни коси или празни места користејќи го регуларниот израз [\/ ]+
. Ова ја дели линијата inet 172.17.0.11/16
во посебни полиња. IP-адресата е во третото поле бидејќи празнините на почетокот на линијата исто така се бројат како поле, бидејќи сте разграничени со празни места, како и со коси. Забележете дека awk
ги третираше последователните празни места како единствен простор во овој случај.
Излезот ја покажува IP адресата:
Output172.17.0.11
Ќе најдете многу места каде што можете да користите awk
за пребарување или анализирање на излезот од други команди.
Заклучок
Досега треба да имате основно разбирање за тоа како можете да ја користите командата awk
за манипулирање, форматирање и селективно печатење текстуални датотеки и текови на текст. Сепак, Awk е многу поголема тема и всушност е цел програмски јазик полн со доделување променливи, контролни структури, вградени функции и многу повеќе. Можете да го користите во вашите сопствени скрипти за да го форматирате текстот на сигурен начин.
За да дознаете повеќе за awk
, можете да ја прочитате бесплатната книга од јавен домен од нејзините создавачи, која навлегува во многу повеќе детали.