- awk je alat i skriptni jezik orijentisan na obradu teksta po linijama i kolonama, idealan za filtriranje, transformisanje i analizu izlaza naredbe i fajlove.
- Omogućava vam definiranje obrazaca i akcija kombiniranjem regularnih izraza, specijalnih varijabli kao što su $0, $1, NF ili NR, i funkcija kao što su length, substr ili match kako biste napravili vrlo precizne filtere.
- awk udobno radi sa delimiterima i poljima koristeći FS, OFS i opcije poput -F, i može formatu izlazi sa print i printf, izvršavaju matematičke operacije i upravljaju varijablama sa -v.
- Moguće je kreirati kompletne awk skripte koje automatiziraju složene zadatke, uključujući pretrage i zamjene pomoću gsub-a, napredne proračune i generiranje izvještaja iz naredbi kao što su ps, df ili sistemske datoteke.

Kada počneš ozbiljno shvatati konzolu Linux Otkrivate da rad s tekstom nije samo pregledavanje datoteka pomoću cat I to je otprilike to. Čim uđete u rezanje Za ogromne liste procesa, izlaza naredbi ili CSV datoteka, potrebno vam je nešto mnogo moćnije za filtriranje, transformaciju i sumiranje podataka bez izluđivanja.
Tu nastupa awk.: komanda koja je, više od jednostavnog filtera, praktično jezik programiranje Awk je alat za obradu teksta koji vam omogućava pretraživanje obrazaca, odabir kolona, izvršavanje proračuna, definiranje uvjeta, korištenje varijabli, petlji, funkcija, pa čak i pisanje kompletnih skripti. U ovom awk tutorijalu za Linux, istražit ćemo ga korak po korak, od osnova do prilično napredne upotrebe, uključujući sve vrste primjera iz stvarne konzole.
Šta je awk i za šta se koristi u Linuxu?
Awk je i alat za komandnu liniju i skriptni jezik. Dizajniran za analizu teksta strukturiranog u redove i polja, njegovo ime potiče od inicijala njegovih tvoraca (Aho, Weinberger i Kernighan). Koristi se od kasnih 70-ih, ali ostaje ključna komponenta u svakom okruženju. Unix ili GNU/Linux (na primjer, za Pokrenite stari Unix na vašem računaru).
Filozofija awk-a je vrlo jednostavna.Iterira kroz datoteku (ili izlaz komande) red po red, dijeli svaki red u kolone prema separatoru, provjerava da li je uslov ispunjen i, ako jeste, izvršava akciju. Ako ne navedete uslov, akcija se primjenjuje na sve redove; ako ne navedete akciju, podrazumevana akcija je ispis cijelog reda.
Pomoću ovog jednostavnog mehanizma možete postići zaista nevjerovatne stvari.: od prikazivanja samo nekih kolona od ps o df...do izračunavanja ukupnih iznosa, filtriranja po složenim obrascima pomoću regularnih izraza, zamjene teksta, formatiranja izvještaja, rada s CSV datotekama ili čak pisanja skripti od nekoliko desetina redova.
Iako vas awk može malo podsjećati na grep ili sedNjegov pristup je strukturiraniji: zamislite redove kao zapise, a riječi (ili polja) kao kolone, s internim varijablama i mini-jezikom koji ga čini idealnim za brzu obradu tabelarnih podataka.
U praksi, ako želite početi pisati odgovarajuće shell skripte...Gotovo je obavezno znati awk, kao i druge alate poput sed, grep, cut i kompanija. Oni su osnovni gradivni blokovi za obradu teksta u Linuxu.
Instalirajte i pokrenite awk (gawk) na vašem sistemu
U većini modernih GNU/Linux distribucijaawk je već instaliran po defaultu, obično u GNU awk varijanti (gawkMožete to provjeriti sa:
awk --version
Ako iz nekog razloga nemate instaliranU Debianu, Ubuntuu i derivatima možete koristiti upravitelj paketa:
sudo apt update && sudo apt install gawk
Također je dostupan na macOS-u.Možete koristiti sistemsku verziju ili instalirati ažuriranu verziju pomoću Homebrewa:
brew install gawk
Jednom instaliran, awk se uvijek koristi s istom idejom.Instrukcije se prosljeđuju između navodnika i datoteke (ili se izlaz druge naredbe proslijedi putem cijevi). Na primjer:
awk '{print}' archivo.txt
Awk možete koristiti i kao interpreter skripti., što u prvom redu datoteke označava putanju do izvršne datoteke:
#!/usr/bin/awk -f
a zatim pokretanje skripta direktno ili sa awk -f script.awk.
Osnovna sintaksa: obrasci i akcije

Minimalna struktura awk-a je:
awk 'patrón { acción }' fichero
Svaki red datoteke se poredi sa uzorkom.Ako se podudara, izvršava se radnja unutar vitičastih zagrada. Ako izostavite uzorak, radnja se primjenjuje na sve redove. Neke ključne ideje:
Posebne varijable koje se odnose na svaki red:
$0: kompletna linija.$1, $2, $3, …: polja (kolone) linije, odvojena definiranim razdjelnikom.NF: broj polja u trenutnoj liniji.NR: trenutni registracijski broj (globalni broj linije).FNR: broj linije unutar trenutne datoteke, korisno pri obradi više datoteka.
Posebna uputstva:
BEGIN { … }: blok koji se izvršava prije čitanja bilo koje linije.END { … }: blok koji se izvršava nakon obrade svih linija.
Najčešće izlazne naredbe:
print: ispisuje argumente odvojene izlaznim separatorom (OFS(podrazumevano, razmak).printfslično kaoprintfU C-u, omogućava detaljno formatiranje bez dodavanja automatskih prekida reda.
Minimalni primjer za ispis datoteke tačno onakve kakva jeste, kao da je cat:
awk '{print}' archivo.txt
Ili ako želite da se prikaže i dužina svake linije:
awk '{print length, "\t", $0}' archivo.txt
Rad sa kolonama i separatorima u awk-u
Jedna od glavnih upotreba awk-a je manipulisanje kolonama. iz izlaznih komandi kao što su ps, df ili datoteke poput /etc/passwdPodrazumevano, awk smatra bilo koji razmak ili tabulator kao separator, ali možete koristiti praktično bilo koji separator.
Odaberite određene kolone
Zamislite izlazak iz ps sa nekoliko kolona (PID, TTY, TIME, CMD…)Ako želite vidjeti samo PID-ove, jednostavno:
ps | awk '{print $1}'
Ako vas zanima druga kolona (na primjer, TTY):
ps | awk '{print $2}'
A ako želite preskočiti prvi red (zaglavlje)Možete filtrirati po registracijskom broju:
ps | awk 'NR>1 {print $1}'
Ideja je vrlo jednostavna.: svaki broj nakon simbola $ Odnosi se na odgovarajuću kolonu, uvijek u odnosu na trenutni separator.
Promijenite razdjelnik sa -F i sa FS
Mnoge sistemske datoteke nisu odvojene razmacima.ali od strane drugih simboliKlasik je /etc/passwdgdje su polja odvojena sa :Za obradu te datoteke po kolonama imate dvije opcije: opciju -F na komandnoj liniji ili varijabli FS unutar bloka BEGIN.
Korištenje -F u komandnoj liniji:
cat /etc/passwd | awk -F ":" '{print $1}'
Ovaj primjer prikazuje samo korisnička imena (prvo polje) jer je separator sada :Ako želite i UID i GID (polja 3 i 4), jednostavno:
cat /etc/passwd | awk -F ":" '{print $1, $3, $4}'
Problem s ovom naredbom je što je izlaz slijepljen. Ako ne definirate eksplicitne separatore, možete ručno dodati razmake ili tabulatore:
cat /etc/passwd | awk -F ":" '{print $1 " " $3 " " $4}'
Ako želite tabelarniji rezultatmožete koristiti \t za umetanje tabulatora:
cat /etc/passwd | awk -F ":" '{print $1 "\t" $3 "\t" $4}'
Alternativa sa FS u BEGIN bloku Omogućava vam da postavite separator unutar same awk skripte:
cat /etc/passwd | awk 'BEGIN { FS=":" } {print $1 "\t" $3 "\t" $4}'
Oba pristupa su funkcionalno ekvivalentnaiako korištenje BEGIN {FS=...} Obično je čišće kada pišete .awk skripte koje se mogu ponovo koristiti.
FS i OFS: ulazni i izlazni separatori
Pored FS-a (separatora polja), awk ima i OFS (separator izlaznih polja).koji definira kako su polja odvojena kada koristite print sa zarezima:
cat /etc/passwd | awk 'BEGIN { FS=":"; OFS=" - " } {print $1, $3, $4}'
U ovom slučaju, čitate sa : ali pišeš sa - , generirajući izlaz poput:
root - 0 - 0
daemon - 1 - 1
...
Ova kombinacija FS/OFS je veoma korisna za "preformatiranje" podataka.Na primjer, za konverziju iz jednog formata u drugi ili za pripremu čitljivih izlaza koje zatim izvozite u drugi sistem.
Dohvati posljednje polje sa $NF (i prethodna)
U mnogim izlazima komandiPolje koje vas zanima je na kraju, ali tačan broj kolona varira. Tu se nalazi $NF (Broj polja) pojednostavljuje vam život: to je uvijek posljednje polje u trenutnom redu.
Na primjer, u /etc/shells Važeće putanje ljuske se pojavljuju na kraju svake linijePonekad u drugoj koloni, ponekad u trećoj, itd. Da biste odštampali samo naziv ljuske (dio nakon posljednje kose crte):
awk -F "/" '/^\// {print $NF}' /etc/shells
Ako želite zadržati samo jedinstvene vrijednosti (bez duplikata), možete ulančati sa uniq:
awk -F "/" '/^\// {print $NF}' /etc/shells | uniq
A ako vas zanima pretposljednji element puta (na primjer, prethodni direktorij), možete koristiti $(NF-1) o $(NF-2):
awk -F "/" '/^\// {print $(NF-1)}' /etc/shells
awk -F "/" '/^\// {print $(NF-2)}' /etc/shells
Filtrirajte linije sa obrascima, dužinom i logičkim uslovima
Awk je odličan kada se želite držati samo određenih redova. na osnovu tekstualnih obrazaca, specifičnih kolona ili numeričkih uslova. Kombinujte regularne izraze, logičke operatore i funkcije kao što su length za izradu vrlo preciznih filtera.
Filtriraj po obrascima i regularnim izrazima
Najdirektniji način filtriranja po sadržaju je stavljanje regularnog izraza između kosih crta. Neposredno prije ključeva:
awk '/patrón/ {print}' archivo.txt
Na primjer, s odlaskom df Možete prikazati samo redove koji počinju kosom crtom (montirani datotečni sistemi):
df | awk '/^\// {print}'
Ako želite određenu particiju, na primjer /dev/sda5:
df | awk '/^\/dev\/sda5/ {print}'
Također možete filtrirati po uzorcima na početku ili kraju reda koristeći ^ y $:
awk '/^tmpfs/ {print}' archivo.txt
awk '/\/shm$/ {print}' archivo.txt
I kombinujte nekoliko kriterija logičkim operatorom &&Na primjer, linije koje počinju sa tmpfs i završavaju se u /dev/shm:
df | awk '/\/shm$/ && /^tmpfs/ {print}'
Filtriraj po kolonama i prikaži samo ono što te zanima
Često želite filtrirati ne samo redove, već i kolone.Nastavljajući sa df -h, možete prikazati samo stvarne datotečne sisteme (^/) a zatim zadržite kolone 1, 2 i 3:
df -h | awk '/^\// {print $1 "\t" $2 "\t" $3}'
Awk vam čak omogućava rad s poljima u hoduNa primjer, dodajte kolone 2 i 3 (korišteno + dostupno) da biste vidjeli izračunati „ukupni kapacitet“:
df -h | awk '/^\// {print $1 "\t" $2 + $3}'
Ako želite dodati slovnu jedinicu "G" na kraj rezultata:
df -h | awk '/^\// {print $1 "\t" $2 + $3 "G"}'
Filtriraj po dužini linije koristeći length()
Funkcija length() mjeri broj znakova u nizuObično se koristi sa $0 (puna linija), ali možete ga koristiti i sa određenom kolonom.
Da biste prikazali samo linije od /etc/shells sa više od 9 znakova:
awk 'length($0) > 9' /etc/shells
Ako želite vidjeti dužinu svake linije:
awk '{print length, "\t", $0}' /etc/shells
Također možete filtrirati po dužini, a zatim ispisati samo dužinu.:
awk 'length($0) > 9 {print length}' /etc/shells
Kombinujte više uslova sa && i if
Pored korištenja regularnih izraza na početkuMožete napisati kompletne uslove unutar bloka koristeći if, poređenje i logički operatori.
Na primjer, prikazivanje samo linija od df -h koji počinju sa t i čija kolona 6 ima više od 8 znakova:
df -h | awk '/^t/ && length($6) > 8 {print $0}'
Drugi tipičan slučaj je traženje procesa po posljednjem polju (izvršena naredba) na izlazu od ps -efPosljednje polje je $NFDakle, možete koristiti:
ps -ef | awk '{ if ($NF == "firefox") print $0 }'
Ako vas zanimaju samo PID i komanda:
ps -ef | awk '{ if ($NF == "firefox") print $2, $NF }'
Kontrolne linije sa NR, rasponima i dužinom polja
Varijabla NR (Broj zapisa) Broji koliko je redova do sada pročitano (globalno). Ovo omogućava uobičajene stvari poput preskakanja zaglavlja, ispisa određenih raspona redova ili prikaza samo prvog reda.
Prebroji redove i prikaži samo prvi ili drugi
Da biste prebrojali ukupan broj linija u datoteci bez upotrebe wc -l Možete uraditi:
awk 'END {print NR}' archivo.txt
Ako želite odštampati samo prvi red:
awk 'NR==1 {print}' archivo.txt
I da prikažem samo drugi red:
awk 'NR==2 {print}' archivo.txt
Ispis počevši od određenog reda ili raspona
Da biste prikazali sve linije od treće nadalje Možete koristiti jednostavan uslov sa > o >=:
ps -aux | awk 'NR>2 {print}'
Ako želite raspon, na primjer redove od 2 do 4 en /etc/shells:
cat /etc/shells | awk 'NR==2, NR==4 {print $0}'
Također možete ispisati broj reda pored sadržaja:
cat /etc/shells | awk 'NR==2, NR==4 {print NR, $0}'
Dužina određenih polja
Pored mjerenja dužine punih linijaMožete provjeriti dužinu određene kolone. Na primjer, da biste vidjeli koliko znakova datotečni sistem (kolona 1) ima u izlazu od df -h:
df -h | awk '{print length($1) "\t" $1}'
Ako želite preskočiti zaglavlje (prvi red), dodaje NR>1:
df -h | awk 'NR>1 {print length($1) "\t" $1}'
Korisne funkcije: substr, match, RSTART i RLENGTH
Awk uključuje dobar asortiman tekstualnih funkcijaDva najmoćnija za napredno pretraživanje su substr y match, a potonje je praćeno varijablama RSTART y RLENGTH.
Skrati tekst pomoću substr()
Funkcija substr(cadena, inicio) o substr(cadena, inicio, longitud) Omogućava vam izdvajanje podnizova. Na primjer, uklanjanje prvih 5 znakova iz svakog reda /etc/shells:
cat /etc/shells | awk '{print substr($0, 5)}'
Ako ne želite obraditi prvi red (na primjer, komentar), možete koristiti NR:
cat /etc/shells | awk 'NR>1 {print substr($0, 5)}'
Imajte na umu da je prvi parametar string (obično $0) a drugi označava koji znak želite početi prikazivati.
Lociranje uzoraka pomoću match(), RSTART i RLENGTH
Funkcija match(cadena, /regex/) traži regularni izraz unutar stringaAko se pronađe podudaranje, vraća početnu poziciju (na osnovu 1) i popunjava dvije varijable:
RSTART: pozicija gdje počinje pronađeni uzorak.RLENGTH: dužina utakmice.
Na primjer, za sve linije ps -aux koji sadrže "cpu"Možete prikazati cijelu liniju i poziciju na kojoj se uzorak nalazi:
ps -aux | awk 'match($0, /cpu/) {print $0 " Contiene \"cpu\" en la posición " RSTART}'
Ako želite znati i dimenzije pronađenog uzorka, samo koristite RLENGTH na izlazu:
ps -aux | awk 'match($0, /cpu/) {print $0 " Posición=" RSTART " Longitud=" RLENGTH}'
Ova vrsta pretrage se široko koristi u analizi teksta i bioinformatici.Na primjer, na FASTA datotekama, gdje vas zanima lociranje specifičnih motiva u sekvencama.
Matematičke operacije i varijable u awk-u
Awk nije ograničen samo na prikazivanje teksta: omogućava vam direktno izvođenje numeričkih operacija na poljima, internim varijablama ili vrijednostima koje prosljeđujete iz komandne linije ili iz shell okruženja.
Definišite varijable sa -vy i koristite ih u BEGIN
Varijable možete deklarisati pomoću opcije -v prilikom pozivanja awk-aNa primjer, množenje dva fiksna broja:
awk -v a="10" -v b="20" 'BEGIN {print "La multiplicación de a x b es", a*b}'
Također je moguće proslijediti vrijednosti varijabli iz vašeg shell-aAko u bash-u uradite sljedeće:
a=1.5
b=4
Onda ih možete koristiti u awk-u ovako:
awk -v a="$a" -v b="$b" 'BEGIN {print "La multiplicación de a x b es", a*b}'
BEGIN blok se ovdje koristi jer ne obrađujemo nijednu datoteku.Želimo samo jednom pokrenuti kod i prikazati rezultat.
Matematičke funkcije: sqrt i for petlje
Awk uključuje nekoliko standardnih matematičkih funkcija., kako sqrt() za kvadratne korijene. Na primjer, kvadratni korijen iz 400:
awk 'BEGIN {print sqrt(400)}'
Također ga možete kombinirati s for petljama za generiranje potpunih lista:
awk 'BEGIN { for(i=1; i<=10; i++) print "La raíz cuadrada de", i*i, "es", i }'
Ili prelazite decimalne vrijednosti od 0 do 1 u malim koracima:
awk 'BEGIN { for(i=0; i<=1; i=i+0.00001) print "La raíz cuadrada de", i*i, "es", i }'
Ove vrste struktura čine awk veoma sličnim tradicionalnom jeziku.iako njegovo prirodno stanište ostaje format stupca.
Pisanje i pokretanje kompletnih skripti u awk-u
Kada awk naredbe počnu biti dugačke Ako želite ponovo koristiti složene transformacije, razumno je da ih sačuvate u skript datoteku s ekstenzijom . .awk (iako nije obavezno).
Tipičan primjer uključuje obradu izlaza df prikazati samo određene unose koji ispunjavaju uslove u vezi sa dostupnim prostorom i formatirati rezultate kao malu tabelu.
Zamislite da želite sljedeće:
- Prikaži samo datotečne sisteme čije ime počinje sa "t" (na primjer
tmpfs). - Filtriraj one s dostupnim kapacitetom (kolona 4) većim od 6000K.
- Ispišite samo jedinicu (kolona 1) i zbir kolona 2 i 3 kao približan ukupni prostor.
Možete kreirati skriptu pod nazivom capacidad.awk sa sličnim sadržajem (prilagođeno i pojednostavljeno):
#!/usr/bin/awk -f
BEGIN { printf "%s\n", "Voy a extraer las partes que me interesan del comando df" }
BEGIN { printf "%s\t%s\n", "Unidad", "Capacidad disponible" }
/^t/ && $4 > 6000 {print $1 "\t" $2 + $3 "K"}
A zatim ga izvršite lančanim povezivanjem izlaza funkcije df.:
df | awk -f capacidad.awk
Ako želite poboljšati izgled stola, možete zamijeniti print por printf i koristite formate poput %-12s (tekst poravnat lijevo u 12 znakova) ili %-23d (Decimalni broj od 23 znaka). Ovo vam daje savršenu kontrolu nad poravnavanjem kolona.
Pronađi i zamijeni tekst pomoću gsub()
Awk također može vršiti zamjenu teksta slično onome što biste uradili sa sed-om, koristeći funkciju gsub() (globalna zamjena).
Opća sintaksa je:
gsub("texto_o_regex_a_buscar", "texto_de_reemplazo", destino)
Na primjer, pretpostavimo datoteku geekland.txt s tekstom „Geekland je najbolji tehnološki blog“ i želite promijeniti početno G u g:
awk '{ gsub("G", "g", $0); print $0 }' geekland.txt
Ako ne navedete treći parametar, pretraga se vrši na $0 po defaultuMeđutim, vrlo je uobičajeno ograničiti zamjenu na jednu kolonu:
df -h | awk '{ gsub("M", "G", $2); print $2 }'
U ovom slučaju, promijenili smo jedinicu M u G samo u koloni 2.Ako želite da i kolona 1 bude pravilno poravnata, možete je kombinovati sa printf:
df -h | awk '{ gsub("M", "G", $2); printf "%-12s %-12s\n", $1, $2 }'
Ovaj obrazac „Modifikujem kolonu, a zatim ispisujem formatirano“ Izuzetno je koristan u izvještajima, migracijama podataka ili brzom čišćenju izlaza komandi.
Dodatne upotrebe: mačka zaražena steroidima i izvršavanje naredbi
Iako možda izgleda glupoawk može djelovati kao cat Poboljšano, jer može prikazati datoteku uz dodavanje dodatnih informacija (brojevi linija, dužine itd.).
Trivijalna upotreba bi bila:
awk '{print}' functions.php
Ali možete i numerisati linije ili primijeniti bilo koji filter. bez potrebe za korištenjem bilo kakvih dodatnih alata.
Još jedna zanimljiva činjenica je da awk može izvršavati sistemske naredbe. po funkciji system()Na primjer, za prikaz trenutnog direktorija:
awk 'BEGIN { system("pwd") }'
Ovo nije najčešća praksa u jednostavnim skriptama.Ali dobro je znati da postoji kada gradite složenije alate zasnovane na awk-u.
Awk postaje švicarski nožić za tekst u LinuxuOmogućava vam filtriranje redova, odabir i kombinovanje kolona, zamjenu fragmenata, mjerenje dužina, lociranje obrazaca, sumiranje polja, generisanje malih formatiranih izvještaja, pa čak i kreiranje kompletnih skripti koje obrađuju izlaz drugih naredbi. Kada se jednom savladate, postaje neophodan alat kad god radite sa... terminal i strukturirane podatke.
Strastveni pisac o svijetu bajtova i tehnologije općenito. Volim dijeliti svoje znanje kroz pisanje, a to je ono što ću raditi na ovom blogu, pokazivati vam sve najzanimljivije stvari o gadžetima, softveru, hardveru, tehnološkim trendovima i još mnogo toga. Moj cilj je pomoći vam da se krećete u digitalnom svijetu na jednostavan i zabavan način.