Kako koristiti AWK

Source: http://sparky.rice.edu/~hartigan/awk.html

Awk je moćan jezik komanda koja omogućava korisniku da manipulirati datoteke koje sadrže kolone podataka i gudače. Awk je izuzetno koristan, kako za opšte rad Unix naredbe, i za redukciju podataka (npr IRAF). Možda ćete naučiti kako da koristite editor potok sed. Mnoge aplikacije awk liče na one raditi na PC proračunske tablice.

Ova datoteka sadrži niz primjera kako koristiti awk. Ja sam sastavio ovo sto postepeno tokom nekoliko godina kao što sam naučio da radi nove stvari. Svi koji smanjuje podataka sa IRAF treba naučiti osnove AWK. Učenje učiniti čak i jednostavne stvari će vam puno vremena uštedjeti na duge staze. Trebalo bi da te manje od sat vremena da pročitate ovaj fajl i naučiti osnove.

Postoje dva načina za pokretanje awk. Jednostavan awk komanda se može pokrenuti iz jedne komandne linije. Više kompleks awk skripte treba pisati na komandu datoteku. I predstaviti primjere obje vrste ulaza ispod.

Awk uzima svaku liniju ulaza i pokušava da odgovaraju “obrazac” (vidi dolje), i ako uspije da će učiniti sve što vam to reći da to u {} (zove akcija). Awk najbolje radi na datoteke koje imaju kolone brojeva ili nizova koji su odvojeni razmakom (tabova ili prostora), iako na većini mašine možete koristiti -F opciju ako se podesiti kolona osim po drugi karakter. Awk se odnosi na prvu kolonu $ 1, drugi stupac kao $ 2, itd, a cijela linija kao $ 0. Ako imate datoteku (kao što je katalog) koji uvijek ima brojeva u specifičnim kolone, možete i želite da pokrenete naredbu “colrm ‘i kombiniranje s awk. Tu je i priručnik stranica na colrm. Tu je i vrlo nepotpun čovjek stranica na awk.

Ja ću vas voditi kroz dva primjera. Prvo, pretpostavimo da imate datoteku pod nazivom “file1 ‘koja ima 2 kolone brojeva, a želite napraviti novu datoteku pod nazivom’ file2 ‘koji ima kolone 1 i 2 kao i ranije, ali i dodaje treću kolonu koja je omjer brojevi u kolonama 1. i 2. Pretpostavimo da želite novi 3-kolona file (file2) da sadrži samo one linije sa koloni 1 manji od kolona 2. Ili od sljedeće dvije naredbe radi ono što želite:

awk ‘$ 1 <2 $ {print $ 0, $ 1/2}’ file1> file2

– Ili –

cat file1 | awk ‘$ 1 <2 $ {print $ 0, $ 1/2}’> file2

Pogledajmo drugi. Svi znate da je “mačka file1 ‘ispisuje sadržaj file1 na ekranu. The | (Koji se naziva cijevi) usmjerava izlaz ‘mačka file1’, koji obično ide na ekranu, komandi awk. Awk smatra da je ulaz iz ‘mačka file1’ jednu liniju u jednom trenutku, i pokušava da odgovaraju ‘model’. Obrazac je ono što je između prvog ‘i {, u ovom slučaju je uzorak $ of 1> 2 $. Ako je uzorak lažna, awk nastavlja u sljedeći redak. Ako je uzorak istina, awk radi sve što je u {}. U ovom slučaju smo postavili awk da proverite da li je prva kolona je manje od sekunde. Ako ne postoji obrazac, awk pretpostavlja da je uzorak istina, i ide na akciju sadržane u {}.

Što je akcija? Gotovo uvijek je to otisak izjava neke vrste. U ovom slučaju želimo awk da ispisati cijelu liniju, i.e. $ 0, a zatim ispisati odnos kolona 1 i 2, i.e. $ 1 / $ 2. Mi smo zatvorili akciju sa}, i zatvorite awk naredbu s ‘. Na kraju, za čuvanje krajnji rezultat 3 kolone u file2 (inače to ispisuje na ekran), dodamo ‘> file2’.

Kao drugi primjer, pretpostavimo da imate nekoliko tisuća datoteke koje želite da se preseli u novi direktorij i preimenovati dodavanjem .dat na imena datoteka. Ti bi mogao učiniti jedan po jedan (nekoliko sati), ili koristite vi da pristojno komandu datoteku da to uradi (nekoliko minuta), ili koristiti awk (nekoliko sekundi). Pretpostavimo datoteke se nazivaju junk * (* je džoker za bilo koji niz znakova), i treba da se seli u ../iraf i imaju ‘.dat “u prilogu ime. Da biste to ovaj tip

ls junk * | awk ‘{print “MV” $ 0 Države “../iraf/”$0″.dat”}’ | CSH

ls junk * navodi imena datoteka, i ovaj izlaz je piped u awk umjesto odlaska u ekran. Ne postoji obrazac (ništa između “i {), pa awk nastavlja da štampate nešto za svaku liniju. Na primjer, ako prva dva reda iz ‘ls junk *’ proizvela junk1 i junk2, odnosno, tada awk će ispisati:

mv junk1 ../iraf/junk1.dat
mv junk2 ../iraf/junk2.dat

U ovom trenutku mv komande su jednostavno ispisane na ekranu. Za izvršenje komande uzmemo izlaz awk i cijevi ga natrag u operativni sistem (C-shell). Dakle, da završim izjavu dodamo ‘| CSH ‘.

Više kompleks awk skripte treba pokrenuti iz datoteke. Sintaksa za takve slučajeve je:

cat file1 | awk -f a.awk> file2

gdje file1 je ulazne datoteke, file2 je izlaznu datoteku, a a.awk je datoteka koja sadrži awk naredbe. Primjeri ispod koje sadrže više od jedne linije awk treba pokrenuti iz datoteka.

Neke korisne awk varijable definirane za ste NF (broj stupaca), NR (trenutna linija koja AWK radi na), END (true ako awk dosegne EOF), počnite (istina prije awk piše ništa), a dužina (broj znakova u liniji ili string). Tu je i petlje sposobnost, naredbu za pretragu (/), podniz komanda (izuzetno korisno), i formatirani štampanje na raspolaganju. Postoji logično varijable || (Ili) i && (i) koje se mogu koristiti u “pattern”. Možete definirati i manipulirati svoj korisnički definirane varijable. Primjeri su navedeni u nastavku. Jedini bug ja znam je da Sun verzija awk neće učiniti trigonometrijske funkcije, iako to ne rade za rezanje. Postoji nešto što se zove Gawk (GNU proizvod), koja se bavi još nekoliko stvari od Sunca awk, ali oni su u osnovi isti. Obratite pažnju na upotrebu naredbe ‘da’ dolje. Zajedno s ‘glave’ i ‘awk’ uštedjeti sata kucanja ako imate mnogo datoteka na analizu ili preimenovati.

Sretno!


PRIMJERI # je komentar lik za awk. ‘Polje’ znači ‘kolonu’

# Ispis prva dva polja u obrnutom redoslijedu:
awk ‘{print $ 2, $ 1}’ file
# Print linije duže od 72 znakova:
awk ‘Dužina> 72’ fajl
# Print dužina niza u 2. koloni
‘{Duljina ispisa ($ 2)}’ awk datoteku
# Dodaj up prvoj koloni, print zbroj i prosjek:
{E + = $ 1}
END {print “suma”, e, “prosjek”, s / NR}
# Print polja u obrnutom redoslijedu:
awk ‘{for (i = NF; i> 0; –I) print $ i}’ datoteke
# Ispis zadnja linija
{Linija = $ 0}
KRAJ {print linija}
# Ispis ukupan broj linija koje sadrže riječ Pat
/ Pat / {nlines = nlines + 1}
KRAJ {print nlines}
# Print sve linije između start / stop parova:
awk ‘/ start /, / stop /’ file
# Ispis svih linija čiji je prvi na terenu se razlikuje od prethodnog:
! Awk ‘$ 1 = prev {print; prev = $ 1} ‘file
# Ispis kolona 3 ako kolona 1> kolona 2:
awk ‘$ 1> 2 $ {print $ 3}’ datoteke
# Print liniju ako kolona 3> kolona 2:
awk ‘3 $> $ 2’ file
# Count broj linija gdje col 3> col 1
awk ‘3 $> $ 1 {print i + “1”; i ++} ‘datoteke
# Print redni broj, a zatim koloni 1 file:
awk ‘{print NR, $ 1}’ file
# Ispis svaka linija nakon brisanja 2. polje
awk ‘{$ 2 = “”; print} ‘datoteke
# Print hi 28 puta
Da | glava -28 | awk ‘{print “hi”}’
# Print hi.0010 da hi.0099 (NAPOMENA IRAF KORISNIKA!)
Da | glava -90 | awk ‘{printf ( “hi00% 2.0F \ n”, NR + 9)}’

# Print out 4 slučajnih brojeva između 0 i 1
Da | glava -4 | awk ‘{print rand ()}’

# Print out 40 slučajnih cijelih brojeva modulu 5
Da | glava -40 | awk ‘{print Int (100 * rand ())% 5}’
# Zamijenite svakom polju po apsolutnoj vrijednosti
{For (i = 1; i <= NF; i = i + 1) if ($ i <0) $ i = – $ i print}

# Ako imate još jedan lik koji ograničava polja, koristite -F opcija
# Na primjer, da se ispiše broj telefona za Jones u sljedećim datoteku,
# 000902 | Beavis | Theodore | 333-242-2222 | 149092
# 000901 | Jones | Bill | 532-382-0342 | 234023
# …
# tip
awk -F “|” ‘$ 2 == “Jones” {print $ 4}’ filename

# Neki petlje naredbe
# Uklonite gomilu poslova štampanja iz reda
begin {
for (i = 875; i> 833; i -) {
printf “lprm -Plw% d \ n”, i
} Izlaz
}
Formatiran otisci su oblika printf ( “format \ n”, value1, vrednost2, … valueN)
na primjer printf ( “zdravo% -8S Šta je to brate.% .2f \ n”, $ 1 $ 2 * $ 3)
% S = string
% -8S = 8 znakova lijevo opravdano
% .2f = Broj sa 2 mjesta iza.
% 6.2f = polje 6 znakova sa 2 karaktera poslije.
\ N novi red
\ T karticu
# Print učestalost histogram kolone brojeva
$ Ukupno 2 <= 0,1 {na = na + 1}
($ 2> 0,1) && ($ ukupno 2 <= 0,2) {nb = nb + 1}
($ 2> 0,2) && ($ ukupno 2 <= 0,3) {nc = nc + 1}
($ 2> 0,3) && ($ ukupno 2 <= 0,4) {nd = nd + 1}
($ 2> 0,4) && ($ ukupno 2 <= 0,5) {ne = ne + 1}
($ 2> 0,5) && ($ ukupno 2 <= 0,6) {NF = nf + 1}
($ 2> 0,6) && ($ ukupno 2 <= 0,7) {ng = ng + 1}
($ 2> 0,7) && ($ ukupno 2 <= 0,8) {nh = NH + 1}
($ 2> 0,8) && ($ ukupno 2 <= 0,9) {ni = ni + 1}
($ 2> 0,9) {nj = nj + 1}
KRAJ {print na, nb, NC, nd, NE, NF, ng, NH, ni, nj, NR}
# Pronađite maksimalne i minimalne vrijednosti prisutne u koloni 1
NR == 1 {m = $ 1; p = $ 1}
$ 1 »= m {m = $ 1}
$ 1 <= p {p = $ 1}
END {print “Max =” m “, Min =” p}

# Primjer definiranja varijabli, više naredbi u jednoj liniji
NR == 1 {prev = $ 4; Preva = $ 1; prevb = $ 2; n = 0; suma = 0}
$ 4 = prev {print Preva, prevb, prev, suma / n!; n = 0; suma = 0; prev = $ 4; Preva = $ 1; prevb = 2 $}
$ 4 == prev {n ++; 5 suma = suma + $ / 6 $}
KRAJ {print Preva, prevb, prev, suma / n}

# Primjer definiranja i koristeći funkciju, umetanje vrijednosti u niz
# I rade cijeli aritmetička mod (n). Ova skripta pronalazi broj dana
# Proteklo od Jan 1, 1901. (iz http://www.netlib.org/research/awkbookcode/ch3)
funkcija daynum (y, m, d, dana, i, n)
{# 1 == Jan 1, 1901
Split ( “31 28 31 30 31 30 31 31 30 31 30 31”, dana)
# 365 dana u godini, plus jedan za svaku prestupne godine
n = (y-1901) * 365 + int ((y-1901) / 4)
if (y% 4 == 0) # prijestupna godina 1901-2099
dana [2] ++
for (i = 1; i <m; i ++)
n + = dana [i]
povratak n + d
}
{Print daynum ($ 1 $ 2, $ 3)}

# Primjer uporabe podstringova
# Substr ($ 2,9,7) izdvaja znakove 9-15 kolone 2
{Print “imarith”, substr ($ 2,1,7) “-” $ 3, “out”. Substr ($ 2,5,3)}
{Print “imarith”, substr ($ 2,9,7) “-” $ 3, “out”. Substr ($ 2,13,3)}
{Print “imarith”, substr ($ 2,17,7) “-” $ 3, “out”. Substr ($ 2,21,3)}
{Print “imarith”, substr ($ 2,25,7) “-” $ 3, “out”. Substr ($ 2,29,3)}