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 who
në awk
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 who
në awk
. 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ësFS
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.
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