Si të përdorni komandën awk në Linux


Në Linux, awk është një dinamo e manipulimit të tekstit të linjës së komandës, si dhe një gjuhë e fuqishme skriptimi. Këtu është një hyrje për disa nga veçoritë e tij më interesante.

Sa awk e mori emrin

Komanda awk u emërua duke përdorur inicialet e tre personave që shkruan versionin origjinal në 1977: Alfred Aho, Peter Weinberger dhe Brian Kernighan. Këta tre burra ishin nga panteoni legjendar AT&T Bell Laboratories Unix. Me kontributet e shumë të tjerëve që atëherë, awk ka vazhduar të evoluojë.

Është një gjuhë e plotë skriptimi, si dhe një mjet i plotë i manipulimit të tekstit për vijën e komandës. Nëse ky artikull ju hap oreksin, mund të shikoni çdo detaj rreth awk dhe funksionalitetin e tij.

Rregullat, modelet dhe veprimet

awk funksionon në programe që përmbajnë rregulla të përbëra nga modele dhe veprime. Veprimi ekzekutohet në tekstin që përputhet me modelin. Modelet janë të mbyllura në kllapa kaçurrelë ({}). Së bashku, një model dhe një veprim formojnë një rregull. I gjithë programi awk është i mbyllur në thonjëza të vetme ().

Le të hedhim një vështrim në llojin më të thjeshtë të programit awk. Nuk ka model, kështu që përputhet me çdo rresht të tekstit të futur në të. Kjo do të thotë se veprimi është ekzekutuar në çdo rresht. Ne do ta përdorim atë në dalje nga komanda who.

Këtu është prodhimi standard nga who:

who

Ndoshta nuk na duhen të gjitha këto informacione, por, përkundrazi, thjesht duam të shohim emrat në llogaritë. Mund ta dërgojmë daljen nga whoawk dhe më pas t'i themi awk të printojë vetëm fushën e parë.

Si parazgjedhje, awk e konsideron një fushë si një varg karakteresh të rrethuar me hapësirë të bardhë, fillimin e një rreshti ose fundin e një rreshti. Fushat identifikohen nga një shenjë dollari ($) dhe një numër. Pra, $1 përfaqëson fushën e parë, të cilën do ta përdorim me veprimin print për të printuar fushën e parë.

Ne shtypim sa vijon:

who | awk '{print $1}'

awk printon fushën e parë dhe heq pjesën tjetër të rreshtit.

Mund të printojmë sa më shumë fusha që duam. Nëse shtojmë një presje si ndarës, awk printon një hapësirë midis secilës fushë.

Ne shtypim sa vijon për të shtypur gjithashtu kohën kur personi është identifikuar (fusha katër):

who | awk '{print $1,$4}'

Ka disa identifikues të veçantë të fushës. Këto përfaqësojnë të gjithë rreshtin e tekstit dhe fushën e fundit në rreshtin e tekstit:

  • $0: Përfaqëson të gjithë rreshtin e tekstit.
  • $1: Përfaqëson fushën e parë.
  • $2: Përfaqëson fushën e dytë.
  • 7$: Përfaqëson fushën e shtatë.
  • 45$: Përfaqëson fushën e 45-të.
  • $NF: Qëndron për numrin e fushave dhe përfaqëson fushën e fundit.

Ne do të shkruajmë sa vijon për të sjellë një skedar të vogël teksti që përmban një citat të shkurtër që i atribuohet Dennis Ritchie:

cat dennis_ritchie.txt

Ne dëshirojmë që awk të printojë fushën e parë, të dytë dhe të fundit të kuotimit. Vini re se megjithëse është i mbështjellë në dritaren e terminalit, është vetëm një rresht i vetëm teksti.

Ne shtypim komandën e mëposhtme:

awk '{print $1,$2,$NF}' dennis_ritchie.txt

Ne nuk e dimë atë thjeshtësi. është fusha e 18-të në rreshtin e tekstit dhe nuk na intereson. Ajo që dimë është se është fusha e fundit dhe mund të përdorim $NF për të marrë vlerën e saj. Periudha thjesht konsiderohet si një tjetër personazh në trupin e fushës.

Shtimi i ndarësve të fushës së daljes

Ju gjithashtu mund t'i thoni awk të printojë një karakter të caktuar midis fushave në vend të karakterit të paracaktuar të hapësirës. Dalja e parazgjedhur nga komanda date është paksa e çuditshme sepse koha është e bllokuar pikërisht në mes të saj. Megjithatë, ne mund të shkruajmë sa vijon dhe të përdorim awk për të nxjerrë fushat që duam:

date
date | awk '{print $2,$3,$6}'

Ne do të përdorim variablin OFS (ndarësi i fushës së daljes) për të vendosur një ndarës midis muajit, ditës dhe vitit. Vini re se më poshtë e mbyllim komandën në thonjëza të vetme (), jo në kllapa kaçurrelë ({}):

date | awk 'OFS="/" {print$2,$3,$6}'
date | awk 'OFS="-" {print$2,$3,$6}'

Rregullat e FILLIMIT dhe FUNDIT

Një rregull BEGIN ekzekutohet një herë përpara se të fillojë çdo përpunimi i tekstit. Në fakt, ai ekzekutohet përpara se awk  madje të lexojë ndonjë tekst. Një rregull END ekzekutohet pasi të ketë përfunduar i gjithë përpunimi. Mund të keni rregulla të shumta BEGIN dhe END dhe ato do të ekzekutohen sipas radhës.

Për shembullin tonë të një rregulli BEGIN, ne do të printojmë të gjithë kuotën nga skedari dennis_ritchie.txt që kemi përdorur më parë me një titull sipër tij.

Për ta bërë këtë, ne shtypim këtë komandë:

awk 'BEGIN {print "Dennis Ritchie"} {print $0}' dennis_ritchie.txt

Vini re se rregulli BEGIN ka grupin e vet të veprimeve të mbyllura brenda grupit të tij të kllapave kaçurrelë ({}).

Ne mund të përdorim të njëjtën teknikë me komandën që kemi përdorur më parë për të nxjerrë dalje nga whoawk. Për ta bërë këtë, ne shtypim sa vijon:

who | awk 'BEGIN {print "Active Sessions"} {print $1,$4}'

Ndarësit e fushave hyrëse

Nëse dëshironi që awk të punojë me tekst që nuk përdor hapësirë të bardhë për të ndarë fushat, duhet t'i tregoni se cilin karakter përdor teksti si ndarës i fushës. Për shembull, skedari /etc/passwd përdor një dy pika (:) për të ndarë fushat.

Ne do ta përdorim atë skedar dhe opsionin -F (varg ndarës) për t'i thënë awk të përdorë dy pika (:) si ndarës. Shkruajmë sa vijon për t'i thënë awk të printojë emrin e llogarisë së përdoruesit dhe dosjen kryesore:

awk -F: '{print $1,$6}' /etc/passwd

Dalja përmban emrin e llogarisë së përdoruesit (ose emrin e aplikacionit ose demonit) dhe dosjen kryesore (ose vendndodhjen e aplikacionit).

Shtimi i modeleve

Nëse gjithçka që na intereson janë llogaritë e zakonshme të përdoruesve, mund të përfshijmë një model me veprimin tonë të printimit për të filtruar të gjitha hyrjet e tjera. Për shkak se numrat e ID-së së përdoruesit janë të barabartë ose më të mëdhenj se 1000, ne mund ta bazojmë filtrin tonë në atë informacion.

Ne shtypim sa vijon për të ekzekutuar veprimin tonë të printimit vetëm kur fusha e tretë ($3) përmban një vlerë prej 1000 ose më të madhe:

awk -F: '$3 >= 1000 {print $1,$6}' /etc/passwd

Modeli duhet t'i paraprijë menjëherë veprimit me të cilin lidhet.

Ne mund të përdorim rregullin BEGIN për të dhënë një titull për raportin tonë të vogël. Ne shtypim sa më poshtë, duke përdorur ( ) shënim për të futur një karakter të linjës së re në vargun e titullit:

awk -F: 'BEGIN {print "User Accounts\n-------------"} $3 >= 1000 {print $1,$6}' /etc/passwd

Modelet janë shprehje të rregullta të plota dhe janë një nga lavditë e awk.

Le të themi se duam të shohim identifikuesit universalë unik (UUID) të sistemeve të skedarëve të montuar. Nëse kërkojmë nëpër skedarin /etc/fstab për ndodhitë e vargut UUID, ai duhet të na kthejë atë informacion.

Ne përdorim modelin e kërkimit /UUID/ në komandën tonë:

awk '/UUID/ {print $0}' /etc/fstab

Ajo gjen të gjitha dukuritë e UUID dhe printon ato rreshta. Ne në fakt do të kishim marrë të njëjtin rezultat pa veprimin print sepse veprimi i paracaktuar printon të gjithë rreshtin e tekstit. Megjithatë, për qartësi, shpesh është e dobishme të jesh i qartë. Kur shikoni një skenar ose skedarin tuaj të historisë, do të jeni të lumtur që keni lënë të dhëna për veten tuaj.

Rreshti i parë i gjetur ishte një rresht komenti dhe megjithëse vargu UUID është në mes të tij, awk e gjeti përsëri atë. Ne mund të modifikojmë shprehjen e rregullt dhe t'i themi awk të përpunojë vetëm linjat që fillojnë me UUID. Për ta bërë këtë, ne shtypim sa vijon që përfshin fillimin e shenjës së linjës (^):

awk '/^UUID/ {print $0}' /etc/fstab

Kjo eshte më mirë! Tani, ne shohim vetëm udhëzime origjinale të montimit. Për të përmirësuar edhe më tej daljen, ne shtypim sa vijon dhe e kufizojmë ekranin në fushën e parë:

awk '/^UUID/ {print $1}' /etc/fstab

Nëse do të kishim sisteme të shumta skedarësh të montuar në këtë makinë, do të merrnim një tabelë të rregullt të UUID-ve të tyre.

Funksionet e integruara

awk ka shumë funksione që mund t'i telefononi dhe t'i përdorni në programet tuaja, si nga linja e komandës ashtu edhe në skriptet. Nëse bëni pak gërmime, do ta gjeni shumë të frytshëm.

Për të demonstruar teknikën e përgjithshme për të thirrur një funksion, do të shohim disa numerikë. Për shembull, sa vijon shtyp rrënjën katrore të 625:

awk 'BEGIN { print sqrt(625)}'

Kjo komandë printon arktangjenten 0 (zero) dhe -1 (që ndodh të jetë konstanta matematikore, pi):

awk 'BEGIN {print atan2(0, -1)}'

Në komandën e mëposhtme, ne modifikojmë rezultatin e funksionit atan2() përpara se ta printojmë atë:

awk 'BEGIN {print atan2(0, -1)*100}'

Funksionet mund të pranojnë shprehje si parametra. Për shembull, këtu është një mënyrë e ndërlikuar për të kërkuar rrënjën katrore të 25:

awk 'BEGIN { print sqrt((2+3)*5)}'

awk Scripts

Nëse vija juaj e komandës ndërlikohet ose zhvilloni një rutinë që e dini se do të dëshironi ta përdorni përsëri, mund ta transferoni komandën tuaj awk në një skript.

Në skenarin tonë të shembullit, ne do të bëjmë të gjitha sa vijon:

  • Thuaji shell-it cilin ekzekutues të përdorë për të ekzekutuar skriptin.
  • Përgatitni awk për të përdorur variablin ndarës të fushës FS për të lexuar tekstin hyrës me fusha të ndara me dy pika (:).
  • Përdorni ndarësin e fushave të daljes OFS për t'i thënë awk të përdorë dy pika (:) për të ndarë fushat në dalje.
  • Cakto një numërues në 0 (zero).
  • Vendosni fushën e dytë të çdo rreshti teksti në një vlerë bosh (është gjithmonë një x, kështu që ne nuk kemi nevojë ta shohim atë).
  • Shtypni rreshtin me fushën e dytë të modifikuar.
  • Rritni numëruesin.
  • Shtypni vlerën e numëruesit.

Skripti ynë është paraqitur më poshtë.

Rregulli BEGIN kryen hapat përgatitorë, ndërsa rregulli END shfaq vlerën e numëruesit. Rregulli i mesëm (i cili nuk ka emër, as model, kështu që përputhet me çdo rresht) modifikon fushën e dytë, printon rreshtin dhe rrit numëruesin.

Rreshti i parë i skriptit i tregon shell-it se cilin ekzekutues të përdorë (awk, në shembullin tonë) për të ekzekutuar skriptin. Ai kalon gjithashtu opsionin -f (emri i skedarit) te awk, i cili e informon atë teksti që do të përpunojë do të vijë nga një skedar. Ne do t'ia kalojmë emrin e skedarit skriptit kur ta ekzekutojmë.

Ne kemi përfshirë skriptin më poshtë si tekst në mënyrë që të mund të prerë dhe ngjitur:

#!/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"
}

Ruajeni këtë në një skedar të quajtur omit.awk. Për ta bërë skriptin të ekzekutueshëm, ne shtypim sa vijon duke përdorur chmod:

chmod +x omit.awk

Tani, ne do ta ekzekutojmë atë dhe do t'ia kalojmë skedarin /etc/passwd në skript. Ky është skedari awk që do të përpunojë për ne, duke përdorur rregullat brenda skriptit:

./omit.awk /etc/passwd

Skedari përpunohet dhe çdo rresht shfaqet, siç tregohet më poshtë.

Regjistrimet x në fushën e dytë u hoqën, por vini re se ndarësit e fushave janë ende të pranishëm. Linjat numërohen dhe totali jepet në fund të prodhimit.

awk Nuk qëndron për Awkward

awk nuk qëndron për siklet; ajo qëndron për elegancën. Është përshkruar si një filtër përpunimi dhe një shkrues raporti. Më saktë, janë të dyja këto, ose, më saktë, një mjet që mund ta përdorni për të dyja këto detyra. Në vetëm disa rreshta, awk arri atë që kërkon kodim të gjerë në një gjuhë tradicionale.

Kjo fuqi shfrytëzohet nga koncepti i thjeshtë i rregullave që përmbajnë modele, që zgjedhin tekstin për t'u përpunuar dhe veprime që përcaktojnë përpunimin.

RELATED: Best Linux Laptops for Developers and Enthusiasts