Како да ја користите командата 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 го постигнува она што бара опширно кодирање на традиционален јазик.

Таа моќ е искористена со едноставниот концепт на правила кои содржат обрасци, кои го избираат текстот за обработка и дејства кои ја дефинираат обработката.

RELATED: Best Linux Laptops for Developers and Enthusiasts