Portál AbcLinuxu, 1. května 2025 07:07
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:
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 ... donepouží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.