Како да ја користите командата awk на Linux
На Linux, awk
е динамо за манипулација со текст во командната линија, како и моќен јазик за скриптирање. Еве еден вовед во некои од неговите најкул карактеристики.
Колку необично го доби своето име
Командата awk
беше именувана со помош на иницијалите на тројцата луѓе кои ја напишаа оригиналната верзија во 1977 година: Алфред Ахо, Питер Вајнбергер и Брајан Керниган. Овие тројца мажи беа од легендарниот пантеон AT&T Bell Laboratories Unix. Со придонесите на многу други оттогаш, awk
продолжи да се развива.
Тоа е целосен јазик за скриптирање, како и комплетна алатка за манипулација со текст за командната линија. Ако оваа статија ви го отвори апетитот, можете да ги проверите сите детали за awk
и неговата функционалност.
Правила, обрасци и дејства
awk
работи на програми кои содржат правила составени од обрасци и дејства. Дејството се извршува на текстот што одговара на шаблонот. Моделите се затворени во кадрави загради ({}
). Заедно, шема и акција формираат правило. Целата програма awk
е затворена во единечни наводници ().
Ајде да го разгледаме наједноставниот тип на програма awk
. Нема шема, па се совпаѓа со секоја линија текст внесен во него. Ова значи дека дејството се извршува на секоја линија. Ќе го користиме на излезот од командата who
.
Еве го стандардниот излез од who
:
who
Можеби не ни требаат сите тие информации, туку само сакаме да ги видиме имињата на сметките. Можеме да го внесеме излезот од who
во awk
, а потоа да му кажеме на awk
да го печати само првото поле.
Стандардно, awk
смета дека полето е низа од знаци опкружени со празно место, почеток на линија или крај на линија. Полињата се идентификуваат со знак за долар ($
) и број. Значи, $1
го претставува првото поле, кое ќе го користиме со дејството print
за печатење на првото поле.
Го пишуваме следново:
who | awk '{print $1}'
awk
го печати првото поле и го отфрла остатокот од линијата.
Можеме да печатиме онолку полиња колку што сакаме. Ако додадеме запирка како раздвојувач, awk
печати празно место помеѓу секое поле.
Го пишуваме следново за да го испечатиме и времето кога лицето се најавило (поле четири):
who | awk '{print $1,$4}'
Постојат неколку посебни идентификатори на поле. Тие ја претставуваат целата линија на текст и последното поле во линијата на текстот:
- $0: ја претставува целата линија на текст.
- $1: го претставува првото поле.
- $2: го претставува второто поле.
- 7$: Го претставува седмото поле.
- 45$: го претставува 45-тото поле.
- $NF: значи „број на полиња“ и го претставува последното поле.
Ќе го напишеме следново за да се појави мала текстуална датотека што содржи краток цитат припишан на Денис Ричи:
cat dennis_ritchie.txt
Сакаме awk
да ги испечати првото, второто и последното поле од понудата. Забележете дека иако е завиткан во терминалниот прозорец, тоа е само една линија текст.
Ја пишуваме следнава команда:
awk '{print $1,$2,$NF}' dennis_ritchie.txt
Не ја знаеме таа „едноставност“. е 18-то поле во редот на текстот и не ни е грижа. Она што го знаеме е дека тоа е последното поле и можеме да користиме $NF
за да ја добиеме неговата вредност. Периодот само се смета за уште еден лик во телото на теренот.
Додавање на сепаратори на излезни полиња
Можете исто така да му кажете на awk
да печати одреден знак помеѓу полињата наместо стандардниот знак за празно место. Стандардниот излез од командата date
е малку чуден бидејќи времето е исцртано точно на средината од него. Сепак, можеме да го напишеме следново и да користиме awk
за да ги извлечеме полињата што ги сакаме:
date
date | awk '{print $2,$3,$6}'
Ќе ја користиме променливата OFS
(раздвојувач на излезно поле) за да поставиме раздвојувач помеѓу месецот, денот и годината. Забележете дека подолу командата ја ставаме во единечни наводници (), а не во кадрави загради (
{}
):
date | awk 'OFS="/" {print$2,$3,$6}'
date | awk 'OFS="-" {print$2,$3,$6}'
Правилата BEGIN и END
Правилото BEGIN
се извршува еднаш пред да започне каква било обработка на текст. Всушност, тој се извршува пред awk
дури и да прочита кој било текст. Правилото END
се извршува откако ќе заврши целата обработка. Може да имате повеќе правила BEGIN
и END
и тие ќе се извршуваат по ред.
За нашиот пример за правило BEGIN
, ќе го испечатиме целиот цитат од датотеката dennis_ritchie.txt
што ја користевме претходно со наслов над неа.
За да го сториме тоа, ја пишуваме оваа команда:
awk 'BEGIN {print "Dennis Ritchie"} {print $0}' dennis_ritchie.txt
Забележете дека правилото BEGIN
има свој сет на дејства затворени во сопствената група на кадрави загради ({}
).
Можеме да ја користиме истата техника со командата што ја користевме претходно за да го внесеме излезот од who
во awk
. За да го сториме тоа, го пишуваме следново:
who | awk 'BEGIN {print "Active Sessions"} {print $1,$4}'
Сепаратори на поле за внесување
Ако сакате awk
да работи со текст што не користи празно место за одделување полиња, треба да му кажете кој знак текстот го користи како раздвојувач на полињата. На пример, датотеката /etc/passwd
користи две точки (:
) за да ги одвои полињата.
Ќе ја користиме таа датотека и опцијата -F
(низа за одвојување) за да му кажеме на awk
да ја користи дебелото црево (:
) како сепаратор. Го пишуваме следново за да му кажеме на awk
да го отпечати името на корисничката сметка и домашната папка:
awk -F: '{print $1,$6}' /etc/passwd
Излезот го содржи името на корисничката сметка (или името на апликацијата или демонот) и домашната папка (или локацијата на апликацијата).
Додавање обрасци
Ако сè што нè интересира се редовните кориснички сметки, можеме да вклучиме шема со нашето дејство за печатење за да ги филтрираме сите други записи. Бидејќи броевите за ID на корисникот се еднакви или поголеми од 1.000, можеме да го засноваме нашиот филтер на тие информации.
Го пишуваме следново за да го извршиме нашето дејство за печатење само кога третото поле ($3
) содржи вредност од 1.000 или поголема:
awk -F: '$3 >= 1000 {print $1,$6}' /etc/passwd
Моделот треба веднаш да му претходи на дејството со кое е поврзан.
Можеме да го користиме правилото BEGIN
за да обезбедиме наслов за нашиот мал извештај. Го пишуваме следново, користејќи ја ознаката (\n
) за да вметнеме знак од нова линија во насловната низа:
awk -F: 'BEGIN {print "User Accounts\n-------------"} $3 >= 1000 {print $1,$6}' /etc/passwd
Шаблоните се полноправни редовни изрази и тие се една од славата на awk
.
Да речеме дека сакаме да ги видиме универзално единствените идентификатори (UUID) на монтираните датотечни системи. Ако бараме низ датотеката /etc/fstab
за појава на низата „UUID“, таа треба да ни ја врати таа информација.
Ние ја користиме шемата за пребарување „/UUID/“ во нашата команда:
awk '/UUID/ {print $0}' /etc/fstab
Ги наоѓа сите појави на „UUID“ и ги печати тие линии. Ние всушност би го добиле истиот резултат без дејството print
бидејќи стандардното дејство ја печати целата линија на текст. Сепак, за јасност, често е корисно да се биде експлицитен. Кога ќе погледнете низ скрипта или датотека со историја, ќе ви биде мило што оставивте индиции за себе.
Првата пронајдена линија беше линија за коментари, и иако низата „UUID“ е во средината на неа, awk
сепак ја најде. Можеме да го измениме регуларниот израз и да му кажеме на awk
да обработува само линии што почнуваат со „UUID“. За да го сториме тоа, го пишуваме следново што го вклучува токенот за почеток на линијата (^
):
awk '/^UUID/ {print $0}' /etc/fstab
Тоа е подобро! Сега гледаме само оригинални упатства за монтирање. За да го подобриме излезот уште повеќе, го пишуваме следново и го ограничуваме приказот на првото поле:
awk '/^UUID/ {print $1}' /etc/fstab
Ако имавме повеќе датотечни системи монтирани на оваа машина, ќе добиевме уредна табела со нивните UUID.
Вградени функции
awk
има многу функции што можете да ги повикате и да ги користите во вашите сопствени програми, и од командната линија и во скриптите. Ако се занимавате со копање, ќе го најдете многу плодно.
За да ја демонстрираме општата техника за повикување функција, ќе погледнеме некои нумерички. На пример, следново го печати квадратниот корен од 625:
awk 'BEGIN { print sqrt(625)}'
Оваа команда го печати арктангенсот од 0 (нула) и -1 (што се случува да биде математичка константа, пи):
awk 'BEGIN {print atan2(0, -1)}'
Во следната команда, го менуваме резултатот од функцијата atan2()
пред да го испечатиме:
awk 'BEGIN {print atan2(0, -1)*100}'
Функциите можат да прифатат изрази како параметри. На пример, еве еден сложен начин да го побарате квадратниот корен од 25:
awk 'BEGIN { print sqrt((2+3)*5)}'
awk скрипти
Ако вашата командна линија се комплицира или развиете рутина за која знаете дека ќе сакате повторно да ја користите, можете да ја пренесете вашата команда awk
во скрипта.
Во нашиот пример скрипта, ќе го направиме сето следново:
- Кажете ѝ на школката која извршна датотека да користи за да ја изврши скриптата.
- Подгответе го
awk
за да ја користите променливата за раздвојување на полињатаFS
за читање на влезен текст со полиња одделени со две точки (:
). - Користете го сепараторот за излезни полиња
OFS
за да му кажете наawk
да користи две точки (:
) за да ги одвои полињата на излезот. - Поставете бројач на 0 (нула).
- Поставете го второто поле од секој ред текст на празна вредност (секогаш е „x“, така што не треба да го гледаме).
- Испечатете ја линијата со изменетото второ поле.
- Зголемете го бројачот.
- Испечати ја вредноста на бројачот.
Нашето сценарио е прикажано подолу.
Правилото BEGIN
ги извршува подготвителните чекори, додека правилото END
ја прикажува вредноста на бројачот. Средното правило (кое нема име, ниту шема за да одговара на секоја линија) го модифицира второто поле, ја печати линијата и го зголемува бројачот.
Првата линија од скриптата и кажува на школката која извршна датотека да користи (awk
, во нашиот пример) за да ја изврши скриптата. Исто така, ја пренесува опцијата -f
(име на датотека) на awk
, што го информира текстот што ќе го обработи ќе доаѓа од датотека. Ќе го пренесеме името на датотеката на скриптата кога ќе ја извршиме.
Скриптата подолу ја вклучивме како текст за да можете да исечете и залепите:
#!/usr/bin/awk -f
BEGIN {
# set the input and output field separators
FS=":"
OFS=":"
# zero the accounts counter
accounts=0
}
{
# set field 2 to nothing
$2=""
# print the entire line
print $0
# count another account
accounts++
}
END {
# print the results
print accounts " accounts.\n"
}
Зачувајте го ова во датотека наречена omit.awk
. За да ја направиме скриптата извршна, го пишуваме следново користејќи chmod
:
chmod +x omit.awk
Сега, ќе го извршиме и ќе ја пренесеме датотеката /etc/passwd
на скриптата. Ова е датотеката awk
што ќе ја обработи за нас, користејќи ги правилата во скриптата:
./omit.awk /etc/passwd
Датотеката се обработува и секоја линија се прикажува, како што е прикажано подолу.
Записите „x“ во второто поле беа отстранети, но имајте предвид дека раздвојувачите на полињата сè уште се присутни. Линиите се бројат и вкупниот број е даден на дното на излезот.
awk Не значи незгодно
awk
не значи непријатно; се залага за елеганција. Опишан е како филтер за обработка и пишувач на извештаи. Поточно, тоа е и двете од овие, или, подобро кажано, алатка што можете да ја користите за двете од овие задачи. Во само неколку редови, awk
го постигнува она што бара опширно кодирање на традиционален јазик.
Таа моќ е искористена со едноставниот концепт на правила кои содржат обрасци, кои го избираат текстот за обработка и дејства кои ја дефинираат обработката.
Linux Commands | ||
Files | tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · look · strings · type · rename · zip · unzip · mount · umount · install · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · patch · convert · rclone · shred · srm · scp · gzip · chattr · cut · find · umask · wc | |
Processes | alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · shutdown · reboot · halt · poweroff · passwd · lscpu · crontab · date · bg · fg · pidof · nohup · pmap | |
Networking | netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw · arping · firewalld |
RELATED: Best Linux Laptops for Developers and Enthusiasts