AWK je výkonný datově řízený programovací jazyk, jehož původ sahá až do počátků Unixu. Původně byl vyvinut pro psaní „jednořádkových“ programů, ale od té doby se vyvinul v plnohodnotný programovací jazyk. AWK dostal svůj název z iniciál svých autorů – Aho, Weinbergera a Kernighan. Příkaz awk v Linuxu a dalších unixových systémech vyvolá interpret, který spouští skripty AWK. V nedávných systémech existuje několik implementací awk, jako je mimo jiné gawk (GNU awk), mawk (Minimal awk) a nawk (New awk). Pokud chcete zvládnout awk, podívejte se na níže uvedené příklady.
Porozumění programům AWK
Programy napsané v awk se skládají z pravidel, která jsou jednoduše dvojicí vzorů a akcí. Vzory jsou seskupeny do složené závorky {} a akční část se spustí, kdykoli awk najde texty, které se vzoru shodují. Ačkoli byl awk vyvinut pro psaní jednoduchých řádků, zkušení uživatelé s ním mohou snadno psát složité skripty.
Programy AWK jsou velmi užitečné pro zpracování velkých souborů. Identifikuje textová pole pomocí speciálních znaků a oddělovačů. Nabízí také programovací konstrukce na vysoké úrovni, jako jsou pole a smyčky. Psaní robustních programů pomocí plain awk je tedy velmi proveditelné.
Praktické příklady příkazu awk v systému Linux
Správci běžně používají awk pro extrakci dat a vytváření sestav spolu s jinými typy manipulace se soubory. Níže jsme probrali awk podrobněji. Pečlivě dodržujte příkazy a vyzkoušejte je ve svém terminálu pro úplné pochopení.
1. Tisk konkrétních polí z textového výstupu
Nejpoužívanější příkazy Linuxu zobrazují svůj výstup pomocí různých polí. Pro extrakci konkrétního pole z takových dat běžně používáme linuxový příkaz cut. Níže uvedený příkaz vám však ukazuje, jak to provést pomocí příkazu awk.
$ who | awk '{print $1}'
Tento příkaz zobrazí pouze první pole z výstupu příkazu who. Jednoduše tedy získáte uživatelská jména všech aktuálně přihlášených uživatelů. Zde 1 $ představuje první pole. Musíte použít $N pokud chcete extrahovat N-té pole.
2. Tisk více polí z textového výstupu
--Interpret awk nám umožňuje vytisknout libovolný počet polí. Níže uvedené příklady nám ukazují, jak extrahovat první dvě pole z výstupu příkazu who.
$ who | awk '{print $1, $2}'
Můžete také ovládat pořadí výstupních polí. Následující příklad nejprve zobrazí druhý sloupec vytvořený příkazem who a poté první sloupec ve druhém poli.
$ who | awk '{print $2, $1}'
Jednoduše vynechejte parametry pole ($N ) zobrazíte všechna data.
3. Použijte příkazy BEGIN
Příkaz BEGIN umožňuje uživatelům vytisknout některé známé informace ve výstupu. Obvykle se používá pro formátování výstupních dat generovaných awk. Syntaxe tohoto příkazu je uvedena níže.
BEGIN { Actions} {ACTION}
Akce, které tvoří sekci BEGIN, se spouští vždy. Poté awk přečte zbývající řádky jeden po druhém a zjistí, zda je třeba něco udělat.
$ who | awk 'BEGIN {print "User\tFrom"} {print $1, $2}'
Výše uvedený příkaz označí dvě výstupní pole extrahovaná z výstupu příkazu who.
4. Použijte příkazy END
Můžete také použít příkaz END, abyste se ujistili, že určité akce budou vždy provedeny na konci vaší operace. Jednoduše umístěte sekci END za hlavní sadu akcí.
$ who | awk 'BEGIN {print "User\tFrom"} {print $1, $2} END {print "--COMPLETED--"}'
Výše uvedený příkaz připojí daný řetězec na konec výstupu.
5. Vyhledávání pomocí vzorů
Velká část fungování awk zahrnuje párování vzorů a regulární výraz. Jak jsme již probrali, awk vyhledává vzory v každém vstupním řádku a akci provede pouze při spuštění shody. Naše předchozí pravidla sestávala pouze z akcí. Níže jsme ilustrovali základy porovnávání vzorů pomocí příkazu awk v Linuxu.
$ who | awk '/mary/ {print}'
Tento příkaz zjistí, zda je uživatel mary aktuálně přihlášen nebo ne. Pokud je nalezena jakákoliv shoda, vypíše celý řádek.
6. Extrahovat informace ze souborů
Příkaz awk velmi dobře pracuje se soubory a lze jej použít pro složité úlohy zpracování souborů. Následující příkaz ilustruje, jak awk zpracovává soubory.
$ awk '/hello/ {print}' /usr/share/dict/american-english
Tento příkaz hledá vzor „hello“ v souboru americko-anglického slovníku. Je k dispozici na většině distribucí založených na Linuxu. Na tomto souboru tedy můžete snadno vyzkoušet programy awk.
7. Přečtěte si skript AWK ze zdrojového souboru
Ačkoli je psaní jednořádkových programů užitečné, můžete také psát velké programy zcela pomocí awk. Budete je chtít uložit a spustit program pomocí zdrojového souboru.
$ awk -f script-file $ awk --file script-file
-f nebo –soubor volba nám umožňuje specifikovat soubor programu. Nemusíte však v souboru skriptu používat uvozovky (‘ ‘), protože linuxový shell takto nebude interpretovat programový kód.
8. Nastavte oddělovač vstupních polí
Oddělovač polí je oddělovač, který rozděluje vstupní záznam. Pomocí -F můžeme snadno určit oddělovače polí pro awk nebo –pole-separator volba. Podívejte se na níže uvedené příkazy, abyste viděli, jak to funguje.
$ echo "This-is-a-simple-example" | awk -F - ' {print $1} ' $ echo "This-is-a-simple-example" | awk --field-separator - ' {print $1} '
Funguje to stejně, když se v Linuxu používají soubory skriptů, nikoli jednořádkový příkaz awk.
9. Tisk informací na základě stavu
Příkaz cut pro Linux jsme probrali v předchozí příručce. Nyní vám ukážeme, jak extrahovat informace pomocí awk, pouze pokud jsou splněna určitá kritéria. Budeme používat stejný testovací soubor, jaký jsme použili v této příručce. Takže tam zamiřte a udělejte si kopii test.txt soubor.
$ awk '$4 > 50' test.txt
Tento příkaz vytiskne všechny národy ze souboru test.txt, který má více než 50 milionů obyvatel.
10. Tisk informací porovnáním regulárních výrazů
Následující příkaz awk zkontroluje, zda třetí pole libovolného řádku obsahuje vzor ‚Lira‘, a v případě nalezení shody vytiskne celý řádek. Opět používáme soubor test.txt používaný k ilustraci příkazu linuxového cut. Než budete pokračovat, ujistěte se, že tento soubor máte.
$ awk '$3 ~ /Lira/' test.txt
Pokud chcete, můžete si vybrat pouze tisk konkrétní části jakékoli shody.
11. Spočítejte celkový počet řádků ve vstupu
Příkaz awk má mnoho proměnných pro speciální účely, které nám umožňují snadno provádět mnoho pokročilých věcí. Jednou z takových proměnných je NR, která obsahuje aktuální číslo řádku.
$ awk 'END {print NR} ' test.txt
Tento příkaz vypíše, kolik řádků je v našem souboru test.txt. Nejprve iteruje každý řádek, a jakmile dosáhne END, vypíše hodnotu NR – která v tomto případě obsahuje celkový počet řádků.
12. Nastavte oddělovač výstupního pole
Dříve jsme si ukázali, jak vybrat oddělovače vstupních polí pomocí -F nebo –oddělovač pole volba. Příkaz awk nám také umožňuje určit oddělovač výstupního pole. Níže uvedený příklad to demonstruje na praktickém příkladu.
$ date | awk 'OFS="-" {print$2,$3,$6}'
Tento příkaz vytiskne aktuální datum ve formátu dd-mm-rr. Spusťte datový program bez awk, abyste viděli, jak vypadá výchozí výstup.
13. Pomocí konstrukce If
Stejně jako ostatní populární programovací jazyky poskytuje awk uživatelům také konstrukce if-else. Příkaz if v awk má níže uvedenou syntaxi.
if (expression) { first_action second_action }
Odpovídající akce se provedou pouze v případě, že je podmíněný výraz pravdivý. Níže uvedený příklad to demonstruje pomocí našeho referenčního souboru test.txt .
$ awk '{ if ($4>100) print }' test.txt
Odsazení nemusíte přísně dodržovat.
14. Použití konstrukcí If-Else
Pomocí níže uvedené syntaxe můžete vytvořit užitečné žebříčky if-else. Jsou užitečné při navrhování složitých awk skriptů, které pracují s dynamickými daty.
if (expression) first_action else second_action
$ awk '{ if ($4>100) print; else print }' test.txt
Výše uvedený příkaz vytiskne celý referenční soubor, protože čtvrté pole není větší než 100 na každý řádek.
15. Nastavte šířku pole
Někdy jsou vstupní data značně chaotická a pro uživatele může být obtížné je vizualizovat ve svých sestavách. Naštěstí awk poskytuje výkonnou vestavěnou proměnnou nazvanou FIELDWIDTHS, která nám umožňuje definovat seznam šířek oddělených mezerami.
$ echo 5675784464657 | awk 'BEGIN {FIELDWIDTHS= "3 4 5"} {print $1, $2, $3}'
Je to velmi užitečné při analýze rozptýlených dat, protože můžeme řídit šířku výstupního pole přesně tak, jak chceme.
16. Nastavte oddělovač záznamu
RS nebo Record Separator je další vestavěná proměnná, která nám umožňuje určit, jak jsou záznamy odděleny. Nejprve vytvořte soubor, který bude demonstrovat fungování této proměnné awk.
$ cat new.txt Melinda James 23 New Hampshire (222) 466-1234 Daniel James 99 Phonenix Road (322) 677-3412
$ awk 'BEGIN{FS="\n"; RS=""} {print $1,$3}' new.txt
Tento příkaz analyzuje dokument a vyplivne jméno a adresu obou osob.
17. Proměnné tiskového prostředí
Příkaz awk v Linuxu nám umožňuje snadno tisknout proměnné prostředí pomocí proměnné ENVIRON. Níže uvedený příkaz ukazuje, jak jej použít pro tisk obsahu proměnné PATH.
$ awk 'BEGIN{ print ENVIRON["PATH"] }'
Obsah libovolných proměnných prostředí můžete vytisknout nahrazením argumentu proměnné ENVIRON. Níže uvedený příkaz vypíše hodnotu proměnné prostředí HOME.
$ awk 'BEGIN{ print ENVIRON["HOME"] }'
18. Vynechat některá pole z výstupu
Příkaz awk nám umožňuje vynechat konkrétní řádky z našeho výstupu. Následující příkaz to demonstruje pomocí našeho referenčního souboru test.txt .
$ awk -F":" '{$2=""; print}' test.txt
Tento příkaz vynechá druhý sloupec našeho souboru, který obsahuje název hlavního města pro každou zemi. Můžete také vynechat více než jedno pole, jak ukazuje následující příkaz.
$ awk -F":" '{$2="";$3="";print}' test.txt
19. Odstraňte prázdné řádky
Někdy mohou data obsahovat příliš mnoho prázdných řádků. Pomocí příkazu awk můžete velmi snadno odstranit prázdné řádky. Podívejte se na další příkaz, abyste viděli, jak to funguje v praxi.
$ awk '/^[ \t]*$/{next}{print}' new.txt
Ze souboru new.txt jsme odstranili všechny prázdné řádky pomocí jednoduchého regulárního výrazu a vestavěného awk s názvem next.
20. Odstraňte koncové mezery
Výstup mnoha příkazů Linuxu obsahuje koncové mezery. K odstranění takových mezer, jako jsou mezery a tabulátory, můžeme v Linuxu použít příkaz awk. Podívejte se na níže uvedený příkaz, abyste viděli, jak řešit takové problémy pomocí awk.
$ awk '{sub(/[ \t]*$/, "");print}' new.txt test.txt
Přidejte nějaké koncové mezery do našich referenčních souborů a ověřte, zda je awk odstranil úspěšně nebo ne. V mém počítači to úspěšně provedlo.
21. Zkontrolujte počet polí v každém řádku
Můžeme snadno zkontrolovat, kolik polí je v řádku pomocí jednoduchého awk one-liner. Existuje mnoho způsobů, jak to udělat, ale pro tento úkol použijeme některé z vestavěných proměnných awk. Proměnná NR nám udává číslo řádku a proměnná NF poskytuje počet polí.
$ awk '{print NR,"-->",NF}' test.txt
Nyní můžeme potvrdit, kolik polí je na řádku v našem test.txt dokument. Protože každý řádek tohoto souboru obsahuje 5 polí, jsme si jisti, že příkaz funguje podle očekávání.
22. Ověřte aktuální název souboru
Proměnná awk FILENAME se používá k ověření aktuálního vstupního souboru. Jak to funguje, si ukážeme na jednoduchém příkladu. Může však být užitečný v situacích, kdy název souboru není explicitně znám nebo existuje více než jeden vstupní soubor.
$ awk '{print FILENAME}' test.txt $ awk '{print FILENAME}' test.txt new.txt
Výše uvedené příkazy vytisknou název souboru, na kterém awk pracuje pokaždé, když zpracovává nový řádek vstupních souborů.
23. Ověřte počet zpracovaných záznamů
Následující příklad ukáže, jak můžeme ověřit počet záznamů zpracovaných příkazem awk. Vzhledem k tomu, že velké množství systémových administrátorů Linuxu používá awk pro generování zpráv, je pro ně velmi užitečné.
$ awk '{print "Processing Record - ",NR;} END {print "\nTotal Records Processed:", NR;}' test.txt
Tento awk úryvek často používám, abych měl jasný přehled o svých akcích. Můžete jej snadno vyladit, aby vyhovoval novým nápadům nebo akcím.
24. Tisk celkového počtu znaků v záznamu
Jazyk awk poskytuje praktickou funkci nazvanou length(), která nám říká, kolik znaků je v záznamu přítomno. Je to velmi užitečné v řadě scénářů. Podívejte se rychle na následující příklad, abyste viděli, jak to funguje.
$ echo "A random text string..." | awk '{ print length($0); }'
$ awk '{ print length($0); }' /etc/passwd
Výše uvedený příkaz vypíše celkový počet znaků přítomných na každém řádku vstupního řetězce nebo souboru.
25. Vytiskněte všechny řádky delší než zadaná délka
K výše uvedenému příkazu můžeme přidat některé podmínky a zajistit, aby tiskl pouze ty řádky, které jsou větší než předdefinovaná délka. Je to užitečné, když již máte představu o délce konkrétního záznamu.
$ echo "A random text string..." | awk 'length($0) > 10'
$ awk '{ length($0) > 5; }' /etc/passwd
Můžete vložit více možností a/nebo argumentů pro vyladění příkazu na základě vašich požadavků.
26. Vytiskněte počet řádků, znaků a slov
Následující příkaz awk v Linuxu vytiskne počet řádků, znaků a slov v daném vstupu. K provedení této operace využívá proměnnou NR a také některé základní aritmetiky.
$ echo "This is a input line..." | awk '{ w += NF; c += length + 1 } END { print NR, w, c }'
Ukazuje, že ve vstupním řetězci je 1 řádek, 5 slov a přesně 24 znaků.
27. Vypočítejte četnost slovů
Můžeme kombinovat asociativní pole a smyčku for v awk, abychom vypočítali četnost slov dokumentu. Následující příkaz se může zdát trochu složitý, ale je poměrně jednoduchý, jakmile jasně porozumíte základním konstrukcím.
$ awk 'BEGIN {FS="[^a-zA-Z]+" } { for (i=1; i<=NF; i++) words[tolower($i)]++ } END { for (i in words) print i, words[i] }' test.txt
Pokud máte potíže s jednořádkovým úryvkem, zkopírujte následující kód do nového souboru a spusťte jej pomocí zdroje.
$ cat > frequency.awk BEGIN { FS="[^a-zA-Z]+" } { for (i=1; i<=NF; i++) words[tolower($i)]++ } END { for (i in words) print i, words[i] }
Poté jej spusťte pomocí -f možnost.
$ awk -f frequency.awk test.txt
28. Přejmenovat soubory pomocí AWK
Příkaz awk lze použít k přejmenování všech souborů vyhovujících určitým kritériím. Následující příkaz ukazuje, jak použít awk k přejmenování všech souborů .MP3 v adresáři na soubory .mp3.
$ touch {a,b,c,d,e}.MP3 $ ls *.MP3 | awk '{ printf("mv \"%s\" \"%s\"\n", $0, tolower($0)) }' $ ls *.MP3 | awk '{ printf("mv \"%s\" \"%s\"\n", $0, tolower($0)) }' | sh
Nejprve jsme vytvořili několik demo souborů s příponou .MP3. Druhý příkaz ukazuje uživateli, co se stane, když je přejmenování úspěšné. Nakonec poslední příkaz provede operaci přejmenování pomocí příkazu mv v Linuxu.
29. Vytiskněte druhou odmocninu čísla
AWK nabízí několik vestavěných funkcí pro manipulaci s číslicemi. Jednou z nich je funkce sqrt(). Je to funkce podobná C, která vrací druhou odmocninu daného čísla. Podívejte se rychle na další příklad, abyste viděli, jak to obecně funguje.
$ awk 'BEGIN{ print sqrt(36); print sqrt(0); print sqrt(-16) }'
Protože nemůžete určit druhou odmocninu záporného čísla, výstup zobrazí speciální klíčové slovo nazvané ‚nan‘ namísto sqrt(-12).
30. Vytiskněte logaritmus čísla
Funkce awk log() poskytuje přirozený logaritmus čísla. Bude však fungovat pouze s kladnými čísly, takže si dejte pozor na ověřování vstupů uživatelů. Jinak by někdo mohl prolomit vaše awk programy a získat neprivilegovaný přístup k systémovým prostředkům.
$ awk 'BEGIN{ print log(36); print log(0); print log(-16) }'
Měli byste vidět logaritmus 36 a ověřit, že logaritmus 0 je nekonečno a logaritmus záporné hodnoty je „Není číslo“ nebo nan.
31. Vytiskněte exponenciál čísla
Exponenciála os čísla n poskytuje hodnotu e^n. Obvykle se používá ve skriptech awk, které se zabývají velkými číslicemi nebo složitou aritmetickou logikou. Můžeme generovat exponenciálu čísla pomocí vestavěné funkce awk exp().
$ awk 'BEGIN{ print exp(30); print log(0); print exp(-16) }'
Avšak awk nemůže vypočítat exponenciální hodnotu pro extrémně velká čísla. Takové výpočty byste měli provádět pomocí nízkoúrovňových programovacích jazyků, jako je C, a vkládat hodnotu do svých skriptů awk.
32. Generování náhodných čísel pomocí AWK
Pro generování náhodných čísel můžeme v Linuxu použít příkaz awk. Tato čísla budou v rozsahu 0 až 1, ale nikdy 0 nebo 1. Můžete vynásobit pevnou hodnotu výsledným číslem, abyste získali větší náhodnou hodnotu.
$ awk 'BEGIN{ print rand(); print rand()*99 }'
Funkce rand() nepotřebuje žádný argument. Navíc čísla generovaná touto funkcí nejsou přesně náhodná, ale spíše pseudonáhodná. Navíc je docela snadné předpovědět tato čísla od běhu k běhu. Takže byste se na ně neměli spoléhat při citlivých výpočtech.
33. Barevná upozornění kompilátoru v červené
Moderní kompilátory Linuxu zobrazí varování, pokud váš kód neudržuje jazykové standardy nebo obsahuje chyby, které nezastaví provádění programu. Následující příkaz awk vypíše varovné řádky generované kompilátorem červeně.
$ gcc -Wall main.c |& awk '/: warning:/{print "\x1B[01;31m" $0 "\x1B[m";next;}{print}'
Tento příkaz je užitečný, pokud chcete specificky určit varování kompilátoru. Tento příkaz můžete použít s jakýmkoli jiným kompilátorem než gcc, jen se ujistěte, že jste změnili vzor /:warning:/ pro odrážení konkrétního kompilátoru.
34. Vytiskněte informace o UUID systému souborů
UUID nebo Universally Unique Identifier je číslo, které lze použít k identifikaci zdrojů, jako je souborový systém Linux. Informace o UUID našeho souborového systému můžeme jednoduše vytisknout pomocí následujícího příkazu Linux awk.
$ awk '/UUID/ {print $0}' /etc/fstab
Tento příkaz hledá textové UUID v /etc/fstab soubor pomocí vzorů awk. Vrací komentář ze souboru, který nás nezajímá. Níže uvedený příkaz zajistí, že dostaneme pouze ty řádky, které začínají UUID.
$ awk '/^UUID/ {print $1}' /etc/fstab
Omezuje výstup na první pole. Získáme tedy pouze čísla UUID.
35. Vytiskněte verzi obrázku jádra Linux
Různé linuxové distribuce používají různé obrazy linuxového jádra. Pomocí awk můžeme snadno vytisknout přesný obraz jádra, na kterém je náš systém založen. Podívejte se na následující příkaz, abyste viděli, jak to obecně funguje.
$ uname -a | awk '{print $3}'
Nejprve jsme zadali příkaz uname s -a a poté tato data přenesla do awk. Poté jsme pomocí awk extrahovali informace o verzi obrazu jádra.
36. Přidejte čísla řádků před řádky
Uživatelé se mohou poměrně často setkat s textovými soubory, které neobsahují čísla řádků. Naštěstí můžete snadno přidat čísla řádků do souboru pomocí příkazu awk v Linuxu. Podívejte se pozorně na níže uvedený příklad, abyste viděli, jak to funguje v reálném životě.
$ awk '{ print FNR ". " $0 ;next}{print}' test.txt
Výše uvedený příkaz přidá číslo řádku před každý řádek v našem referenčním souboru test.txt. K vyřešení tohoto problému využívá vestavěnou awk proměnnou FNR.
37. Vytiskněte soubor po seřazení obsahu
Pomocí awk můžeme také vytisknout seřazený seznam všech řádků. Následující příkazy vytisknou názvy všech zemí v našem souboru test.txt v seřazeném pořadí.
$ awk -F ':' '{ print $1 }' test.txt | sort
Další příkaz vytiskne přihlašovací jména všech uživatelů z /etc/passwd soubor.
$ awk -F ':' '{ print $1 }' /etc/passwd | sort
Pořadí řazení můžete snadno změnit úpravou příkazu sort.
38. Vytiskněte si stránku manuálu
Manuálová stránka obsahuje podrobné informace o příkazu awk spolu se všemi dostupnými možnostmi. Je to nesmírně důležité pro lidi, kteří chtějí důkladně ovládat příkaz awk.
$ man awk
Pokud se chcete naučit složité awk funkce, pak vám to bude velmi užitečné. Nahlédněte do této dokumentace, kdykoli narazíte na problém.
39. Vytiskněte si stránku nápovědy
Stránka nápovědy obsahuje souhrnné informace o všech možných argumentech příkazového řádku. Příručku nápovědy pro awk můžete vyvolat pomocí jednoho z následujících příkazů.
$ awk -h $ awk --help
Pokud chcete rychlý přehled všech dostupných možností pro awk, navštivte tuto stránku.
40. Tisk informací o verzi
Informace o verzi nám poskytují informace o sestavení programu. Stránka verze pro awk obsahuje informace, jako jsou jeho autorská práva, nástroje pro kompilaci a tak dále. Tyto informace můžete zobrazit pomocí jednoho z následujících příkazů awk.
$ awk -V $ awk --version
Konec myšlenek
Příkaz awk v Linuxu nám umožňuje dělat nejrůznější věci, včetně zpracování souborů a údržby systému. Poskytuje rozmanitou škálu operací pro snadné zvládnutí každodenních počítačových úloh. Naši redaktoři sestavili tuto příručku se 40 užitečnými příkazy awk, které lze použít pro manipulaci s textem nebo pro správu. Protože AWK je sám o sobě plnohodnotným programovacím jazykem, existuje několik způsobů, jak udělat stejnou práci. Takže se nedivte, proč některé věci děláme jinak. Vždy si můžete vytvořit své vlastní recepty na základě vašich dovedností a zkušeností. Zanechte nám svůj názor, pokud máte nějaké dotazy, dejte nám vědět.