Portál AbcLinuxu, 19. prosince 2025 13:04
Tento je zápis pro především mě, až mě zase popadne nutkání programovat awk v shellu.
Awk je mocný program pro zpracování textu. Jeho název pochází z počátečních jmen autorů Alfred V. Aho, Peter J. Weinberger a Brian W. Kernighan. Použití je následující (viz man awk):
gawk [ argumenty ] -f soubor-s-programem [ -- ] soubor(y) gawk [ argumenty ] [ -- ] text-programu soubor(y) ...
BEGIN {inicializace}
{program}
vzorek
vzorek2 {program1}
/reg. výr./ {program2}
/start/,/stop/ {program3 1}
END {dokončení}
BEGIN byl v programu jako první.awk používá stejné regulární výrazy, jako egrep. start po řádek, který odpovídá vzorku stop
Z předchozí části plyne, že awk je řádkově orientovaný. Není to úplná pravda. Vstup, který awk čte, je dělen do záznamů a implicitním oddělovačem záznamu je znak nového řádku. Záznam (řádek) se dále dělí na jednotlivé položky (fields). Implicitně tvoří oddělovač záznamů znaky mezera, tabulátor a nový řádek.
K jednotlivým položkám se dostaneme pomocí proměnných $1, $2, ... . V proměnné $0 je uložen celý záznam.
| proměnná | význam | ||
|---|---|---|---|
| CONVFMT | formát pro konverzi čísel (viz část proměnné) | ||
| FILENAME | jméno právě zpracovávaného souboru (- značí stdin) | ||
| FS | oddělovač položek v záznamu | ||
| IGNORECASE | nastavena na nenulovou hodnotu určuje, že se bude ignorovat velikost znaků (GNU awk rozšíření) | ||
| NF | počet položek aktuálního záznamu | ||
| NR | počet záznamů (většinou odpovídá číslu řádku) | ||
| RS | oddělovač záznamů |
Co by to bylo za programovací jazyk, kdyby neměl proměnné. Awk umí pouze dva druhy proměnných, čísla a řetězce a typ se rozlišuje podle kontextu. Konverze mezi typy zajišťují C funkce atof (řetězec na číslo) a sprintf (číslo na řetězec, podle obsahu proměnné CONVFMT). Numerická hodnota se přiřadí příkazem foo = 1, řetězec bar = "123". Awk nemá explicitní funkce pro přetypování, takže číslo na řetězec převedeme přiřazením prázdného řetězce - foo "". Řetezec na číslo převedeme přičtením nuly - bar + 0.
Narozdíl od vnitřních proměnných awk, které jsou vyplňovány automaticky, ty ostatní mají implicitně hodnotu nula. Dokud jim není přiřazena hodnota jiná.
Awk obsahuje příkaz print, který vytiskne svůj argument na výstup. Například náhrada příkazu cat soubor v awk vypadá takto: awk '{print}' soubor. Program cat -n soubor by vypadal awk '{print NR" "$0}' soubor. Dále můžeme, podobně jako v shellu, přesměrovat výstup napsáním print > soubor, případně print >> soubor. Nebo dokonce předat jinému programu pomocí roury print | "wall" .
Stejně jako v C můžeme používat formátovaný výstup pomocí příkazu printf. Formátovací znaky jsou shodné s C verzí, takže vás odkáži na man 3 printf, nebo jiný zdroj dokumentace o C.
Awk toho umí daleko více, má příkazy pro kontrolu toku programu (podmínky, cykly), podporu pro pole, možnost deklarovat vlastní funkce (rozšíření GNU awk), vnitřní funkce (vstupní a výstupní, aritmetické, pro práci s řetězci, časové). Dále umožňuje GNU awk práci s některými dev soubory ( print "chyba" > /dev/stderr). Více je v dokumentaci man awk a info awk a na internetu - skvělý manuál Michala Brandejse z muni, oficiální příručku FSF a FAQ z comp.lang.awk.
[1]Tento interval může rovněž označovat řádky v souboru. Program awk 'NR == 10, NR == 30 { print }' vybere řádky 10 až 30.
Tiskni
Sdílej:
Pises, ze BEGIN musi byt na zacatku a END na konci programu. Naopak pan Herold v knize tvrdi, ze tomu tak byt nemusi. Nevim, nezkousel jsem a dokud se nedostanu ke stroji s Linuxem, tak ani nezkusim.
V tuto chvili me napadaji dve otazky, tykajici se Awku:

awk '/regexp/{udelej neco}'
než ručně v shellu procházet každý řádek a grepem ho ověřovat, zda odpovídá onomu regulárnímu výrazu. Mimo to je awk rychlejší.
for u in `awk -F: '{ if ($3>=1000 && $3<60000) print $1; }' /etc/passwd`; do
...
done
používat perl nebo na to psát program v céčku, asi bych se z toho zbláznil.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.