Si të përdorni gjuhën AWK për të manipuluar tekstin në Linux


Prezantimi

Shërbimet Linux shpesh ndjekin filozofinë e dizajnit të Unix. Mjetet inkurajohen të jenë të vogla, të përdorin skedarë teksti të thjeshtë për hyrje dhe dalje dhe të funksionojnë në mënyrë modulare. Për shkak të kësaj trashëgimie, ne kemi funksionalitet të shkëlqyer të përpunimit të tekstit me mjete si sed dhe awk.

awk është një gjuhë programimi dhe përpunues teksti që mund ta përdorni për të manipuluar të dhënat e tekstit në mënyra shumë të dobishme. Në këtë udhëzues, do të eksploroni se si të përdorni mjetin e linjës së komandës awk dhe si ta përdorni atë për të përpunuar tekstin.

Sintaksa bazë

Komanda awk përfshihet si parazgjedhje në të gjitha sistemet moderne Linux, kështu që nuk keni nevojë ta instaloni për të filluar përdorimin e saj.

awk është më i dobishëm kur trajtoni skedarë teksti që janë të formatuar në një mënyrë të parashikueshme. Për shembull, është i shkëlqyer në analizimin dhe manipulimin e të dhënave tabelare. Ai funksionon në bazë rresht pas rreshti dhe përsëritet në të gjithë skedarin.

Si parazgjedhje, ai përdor hapësirën e bardhë (hapësirat, skedat, etj.) për të ndarë fushat. Për fat të mirë, shumë skedarë konfigurimi në sistemin tuaj Linux përdorin këtë format.

Formati bazë i një komande awk është:

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

Ju mund të hiqni ose pjesën e kërkimit ose pjesën e veprimit nga çdo komandë awk. Si parazgjedhje, veprimi i ndërmarrë nëse pjesa \veprim nuk jepet është \print. Kjo thjesht printon të gjitha linjat që përputhen.

Nëse pjesa e kërkimit nuk është dhënë, awk kryen veprimin e listuar në çdo rresht.

Nëse jepen të dyja, awk përdor pjesën e kërkimit për të vendosur nëse linja aktuale pasqyron modelin dhe më pas kryen veprimet në përputhje.

Në formën e tij më të thjeshtë, mund të përdorni awk si cat për të printuar të gjitha rreshtat e një skedari teksti në ekran.

Krijo një skedar favorite_food.txt i cili liston ushqimet e preferuara të një grupi miqsh:

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

Tani përdorni komandën awk për të printuar skedarin në ekran:

  1. awk '{print}' favorite_food.txt

Do të shihni skedarin e printuar në ekran:

Output
carrot sandy wasabi luke sandwich brian salad ryan spaghetti jessica

Kjo nuk është shumë e dobishme. Le të provojmë aftësitë e filtrimit të kërkimit të awk duke kërkuar nëpër skedar tekstin \rërë:

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

Siç mund ta shihni, awk tani printon vetëm rreshtat që kanë karakteret \rërë në to.

Duke përdorur shprehje të rregullta, mund të synoni pjesë të veçanta të tekstit. Për të shfaqur vetëm rreshtin që fillon me shkronjat \rërë, përdorni shprehjen e rregullt ^rërë:

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

Këtë herë, shfaqet vetëm një rresht:

Output
sandwich brian

Në mënyrë të ngjashme, mund të përdorni seksionin e veprimit për të specifikuar se cilat pjesë të informacionit dëshironi të printoni. Për shembull, për të printuar vetëm kolonën e parë, përdorni komandën e mëposhtme:

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

Ju mund t'i referoheni çdo kolone (siç kufizohet nga hapësira e bardhë) nga variablat që lidhen me numrin e kolonës së tyre. Për shembull, kolona e parë është $1, e dyta është $2 dhe mund t'i referoheni të gjithë rreshtit me $0.

Variablat e brendshëm dhe formati i zgjeruar

Komanda awk përdor disa ndryshore të brendshme për të caktuar pjesë të caktuara të informacionit ndërsa përpunon një skedar.

Variablat e brendshëm që përdor awk janë:

  • FILENAME: Referon skedarin aktual të hyrjes.
  • FNR: Referon numrin e regjistrimit aktual në lidhje me skedarin aktual të hyrjes. Për shembull, nëse keni dy skedarë hyrës, kjo do t'ju tregojë numrin e rekordit të secilit skedar në vend që të jetë në total.
  • FS: Ndarësi aktual i fushës përdoret për të treguar secilën fushë në një rekord. Si parazgjedhje, kjo është caktuar në hapësirë të bardhë.
  • NF: Numri i fushave në regjistrimin aktual.
  • NR: Numri i rekordit aktual.
  • OFS: Ndarësi i fushës për të dhënat e nxjerra. Si parazgjedhje, kjo është caktuar në hapësirë të bardhë.
  • ORS: Ndarësi i rekordeve për të dhënat e nxjerra. Si parazgjedhje, ky është një karakter i linjës së re.
  • RS: Ndarësi i të dhënave që përdoret për të dalluar regjistrimet e veçanta në skedarin hyrës. Si parazgjedhje, ky është një karakter i linjës së re.

Ju mund t'i ndryshoni vlerat e këtyre variablave sipas dëshirës për t'iu përshtatur nevojave të skedarëve tuaj. Zakonisht ju e bëni këtë gjatë fazës së inicializimit të përpunimit tuaj.

Kjo na sjell në një koncept tjetër të rëndësishëm. Sintaksa awk është pak më komplekse se ajo që keni përdorur deri më tani. Ekzistojnë gjithashtu blloqe opsionale BEGIN dhe END që mund të përmbajnë komanda për të ekzekutuar para dhe pas përpunimit të skedarit, përkatësisht.

Kjo e bën sintaksën tonë të zgjeruar të duket diçka si kjo:

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

Fjalë kyçe BEGIN dhe END janë grupe specifike kushtesh, ashtu si parametrat e kërkimit. Ato përputhen para dhe pasi dokumenti të jetë përpunuar.

Kjo do të thotë që ju mund të ndryshoni disa nga variablat e brendshëm në seksionin BEGIN. Për shembull, skedari /etc/passwd kufizohet me dy pika (:) në vend të hapësirës së bardhë.

Për të printuar kolonën e parë të këtij skedari, ekzekutoni komandën e mëposhtme:

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

Ju mund të përdorni blloqet BEGIN dhe END për të printuar informacione rreth fushave që po printoni. Përdorni komandën e mëposhtme për të transformuar të dhënat nga skedari në një tabelë, të ndarë bukur me skeda duke përdorur :

  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

Do të shihni këtë dalje:

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

Siç mund ta shihni, mund t'i formatoni gjërat mjaft bukur duke përfituar nga disa nga veçoritë e awk.

Secila nga seksionet e zgjeruara është opsionale. Në fakt, vetë seksioni i veprimit kryesor është opsional nëse përcaktohet një seksion tjetër. Për shembull, mund të bëni gjëra të tilla:

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

Dhe do të shihni këtë dalje:

Output
We can use awk like the echo command

Tani le të shohim se si të kërkojmë tekst brenda fushave të daljes.

Kërkimi në terren dhe shprehjet e përbëra

Në një nga shembujt e mëparshëm, ju printuat rreshtin në skedarin favorite_food.txt që fillonte me \rërë. Kjo ishte e lehtë sepse po kërkonit fillimin e të gjithë rreshtit.

Po sikur të dëshironit të zbulonit nëse një model kërkimi përputhej në fillim të një fushe?

Krijo një version të ri të skedarit favorite_food.txt i cili shton një numër artikulli përpara ushqimit të çdo personi:

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

Nëse dëshironi të gjeni të gjitha ushqimet nga ky skedar që fillojnë me \sa, mund të filloni duke provuar diçka të tillë:

  1. awk '/sa/' favorite_food.txt

Kjo tregon të gjitha rreshtat që përmbajnë \sa:

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

Këtu, ju jeni duke përputhur çdo shembull të \sa në fjalë. Kjo përfundon duke përfshirë gjëra të tilla si \wasabi që ka modelin në mes, ose \rërë që nuk është në kolonën që dëshironi. Në këtë Në rast se ju interesojnë vetëm fjalët që fillojnë me \sa në kolonën e dytë.

Ju mund t'i thoni awk të përputhet vetëm në fillim të kolonës së dytë duke përdorur këtë komandë:

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

Siç mund ta shihni, kjo na lejon të kërkojmë vetëm në fillim të kolonës së dytë për një ndeshje.

Pjesa field_num ~ specifikon se awk duhet t'i kushtojë vëmendje vetëm kolonës së dytë.

Output
3 sandwich brian 4 salad ryan

Po aq lehtë mund të kërkoni për gjëra që nuk përputhen duke përfshirë \!” karakter para tildës (~). Kjo komandë do të kthejë të gjitha rreshtat që nuk kanë një ushqim që fillon me \sa”:

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

Nëse më vonë vendosni se ju interesojnë vetëm rreshtat që nuk fillojnë me \sa dhe numri i artikullit është më i vogël se 5, mund të përdorni një shprehje të përbërë si kjo:

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

Kjo paraqet disa koncepte të reja. E para është aftësia për të shtuar kërkesa shtesë që linja të përputhet duke përdorur operatorin &&. Duke përdorur këtë, ju mund të kombinoni një numër arbitrar kushtesh që rreshti të përputhet. Në këtë rast, ju po përdorni këtë operator për të shtuar një kontroll që vlera e kolonës së parë është më e vogël se 5.

Do të shihni këtë dalje:

Output
1 carrot sandy 2 wasabi luke

Ju mund të përdorni awk për të përpunuar skedarët, por gjithashtu mund të punoni me daljen e programeve të tjera.

Përpunimi i rezultateve nga programe të tjera

Ju mund të përdorni komandën awk për të analizuar daljen e programeve të tjera në vend që të specifikoni një emër skedari. Për shembull, mund të përdorni awk për të analizuar adresën IPv4 nga komanda ip.

Komanda ip a shfaq adresën IP, adresën e transmetimit dhe informacione të tjera për të gjitha ndërfaqet e rrjetit në kompjuterin tuaj. Për të shfaqur informacionin për ndërfaqen e quajtur eth0, përdorni këtë komandë:

  1. ip a s eth0

Do të shihni rezultatet e mëposhtme:

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

Ju mund të përdorni awk për të synuar linjën inet dhe më pas të printoni vetëm adresën IP:

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

Flamuri -F i thotë awk të kufizojë me prerje ose hapësira përpara duke përdorur shprehjen e rregullt [\/ ]+. Kjo ndan rreshtin inet 172.17.0.11/16 në fusha të veçanta. Adresa IP është në fushën e tretë, sepse hapësirat në fillim të rreshtit llogariten gjithashtu si fushë, pasi ju kufizoni me hapësira dhe me prerje. Vini re se awk i trajtoi hapësirat e njëpasnjëshme si një hapësirë të vetme në këtë rast.

Dalja tregon adresën IP:

Output
172.17.0.11

Do të gjeni shumë vende ku mund të përdorni awk për të kërkuar ose analizuar daljen e komandave të tjera.

konkluzioni

Deri tani, duhet të keni një kuptim bazë se si mund të përdorni komandën awk për të manipuluar, formatuar dhe printuar në mënyrë selektive skedarët e tekstit dhe rrjedhat e tekstit. Megjithatë, Awk është një temë shumë më e madhe, dhe në fakt është një gjuhë e tërë programimi e kompletuar me caktime të ndryshueshme, struktura kontrolli, funksione të integruara dhe më shumë. Mund ta përdorni brenda skripteve tuaja për të formatuar tekstin në një mënyrë të besueshme.

Për të mësuar më shumë rreth awk, mund të lexoni librin falas të domenit publik nga krijuesit e tij, i cili shkon në shumë më tepër detaje.