- awk är ett verktyg och skriptspråk inriktat på textbehandling med rader och kolumner, idealiskt för att filtrera, transformera och analysera utdata från kommandon och filer.
- Det låter dig definiera mönster och åtgärder genom att kombinera reguljära uttryck, specialvariabler som $0, $1, NF eller NR, och funktioner som längd, substr eller matchning för att skapa mycket exakta filter.
- awk fungerar bekvämt med avgränsare och fält med hjälp av FS, OFS och alternativ som -F, och kan format utdata med print och printf, utföra matematiska operationer och hantera variabler med -v.
- Det är möjligt att skapa kompletta awk-skript som automatiserar komplexa uppgifter, inklusive sökningar och ersättningar med gsub, avancerade beräkningar och generering av rapporter från kommandon som ps, df eller systemfiler.

När du börjar ta konsolen på allvar Linux Du upptäcker att det inte bara handlar om att titta på filer med text. cat Och det är ungefär allt. Så fort du kommer in i loggar För enorma listor över processer, kommandoutdata eller CSV-filer behöver du något mycket kraftfullare för att filtrera, transformera och sammanfatta data utan att göra dig själv galen.
Det är där awk kommer in i bilden.ett kommando som, mer än ett enkelt filter, praktiskt taget är ett språk för programmering Awk är ett textbehandlingsverktyg som låter dig söka efter mönster, välja kolumner, utföra beräkningar, definiera villkor, använda variabler, loopar, funktioner och till och med skriva kompletta skript. I den här awk-handledningen för Linux utforskar vi det steg för steg, från grunderna till ganska avancerade användningsområden, och inkluderar alla möjliga verkliga konsolexempel.
Vad är awk och vad används det till i Linux?
Awk är både ett kommandoradsverktyg och ett skriptspråk Den är utformad för att analysera text strukturerad i rader och fält och namnet kommer från initialerna till dess skapare (Aho, Weinberger och Kernighan). Den har använts sedan slutet av 70-talet, men är fortfarande en nyckelkomponent i alla miljöer. Unix eller GNU/Linux (till exempel för Kör gamla Unix på din dator).
Filosofin bakom awk är väldigt enkelItererar genom en fil (eller utdata från ett kommando) rad för rad, delar upp varje rad i kolumner enligt en avgränsare, kontrollerar om ett villkor är uppfyllt och utför i så fall en åtgärd. Om du inte anger ett villkor tillämpas åtgärden på alla rader; om du inte anger en åtgärd är standardåtgärden att skriva ut hela raden.
Med denna enkla mekanism kan du göra verkligt upprörande saker.från att bara visa vissa kolumner av ps o df...till att beräkna totaler, filtrera efter komplexa mönster med reguljära uttryck, ersätta text, formatera rapporter, arbeta med CSV-filer eller till och med skriva skript på flera dussin rader.
Även om awk kan påminna dig lite om grep eller sedDess tillvägagångssätt är mer strukturerat: tänk på rader som poster och ord (eller fält) som kolumner, med interna variabler och ett minispråk som gör det idealiskt för att snabbt bearbeta tabelldata.
I praktiken, om du vill börja skriva riktiga shell-skript...Det är nästan obligatoriskt att känna till awk tillsammans med andra verktyg som sed, grep, cut och företag. De är de grundläggande byggstenarna i ordbehandling i Linux.
Installera och kör awk (gawk) på ditt system
I de flesta moderna GNU/Linux-distributionerawk är redan installerat som standard, vanligtvis i GNU awk-varianten (gawkDu kan kontrollera det med:
awk --version
Om du av någon anledning inte har det installeratI Debian, Ubuntu och derivator kan du använda pakethanteraren:
sudo apt update && sudo apt install gawk
Den är även tillgänglig på macOS.Du kan använda systemversionen eller installera en uppdaterad version med Homebrew:
brew install gawk
När awk väl är installerat används den alltid med samma idé.Du skickar instruktioner mellan enkla citattecken och en fil (eller skickar utdata från ett annat kommando). Till exempel:
awk '{print}' archivo.txt
Du kan också använda awk som en skripttolk, som anger sökvägen till den körbara filen på den första raden i filen:
#!/usr/bin/awk -f
och sedan köra skript direkt eller med awk -f script.awk.
Grundläggande syntax: mönster och handlingar

Den minimala strukturen för awk är:
awk 'patrón { acción }' fichero
Varje rad i filen jämförs med mönstret.Om det matchar utförs åtgärden inom klammerparenteserna. Om du utelämnar mönstret tillämpas åtgärden på alla rader. Några viktiga idéer:
Speciella variabler som refererar till varje rad:
$0: hela raden.$1, $2, $3, …: fält (kolumner) på raden, separerade med den definierade avgränsaren.NF: antal fält på den aktuella raden.NR: aktuellt registreringsnummer (globalt linjenummer).FNRradnummer i den aktuella filen, användbart vid bearbetning av flera filer.
Särskilda instruktioner:
BEGIN { … }: block som körs innan någon rad läses.END { … }: block som exekveras efter att alla rader har bearbetats.
Vanligaste utdatakommandon:
print: skriver ut argument separerade med utdataavgränsare (OFS(som standard ett mellanslag).printfliknandeprintfI C möjliggör den detaljerad formatering utan att lägga till automatiska radbrytningar.
Minimalt exempel för att skriva ut en fil exakt som den är, som om den vore cat:
awk '{print}' archivo.txt
Eller om du vill att den även ska visa längden på varje rad:
awk '{print length, "\t", $0}' archivo.txt
Arbeta med kolumner och avgränsare i awk
En av awks bästa användningsområden är att manipulera kolumner från kommandoutdata som ps, df eller filer som /etc/passwdSom standard betraktar awk alla mellanslag eller tabbar som avgränsare, men du kan använda praktiskt taget vilken avgränsare som helst.
Välj specifika kolumner
Föreställ dig utgången av ps med flera kolumner (PID, TTY, TIME, CMD…)Om du bara vill se PID:erna, helt enkelt:
ps | awk '{print $1}'
Om du är intresserad av den andra kolumnen (till exempel TTY):
ps | awk '{print $2}'
Och om du vill hoppa över den första raden (rubriken)Du kan filtrera efter registreringsnummer:
ps | awk 'NR>1 {print $1}'
Idén är väldigt enkel.varje siffra efter symbolen $ Den refererar till motsvarande kolumn, alltid med avseende på den aktuella separatorn.
Ändra avgränsaren med -F och med FS
Många systemfiler är inte separerade med mellanslag.men av andra symbolerEn klassiker är /etc/passwddär fälten är separerade av :För att bearbeta filen kolumnvis har du två alternativ: alternativet -F på kommandoraden, eller variabeln FS inuti ett block BEGIN.
Använda -F på kommandoraden:
cat /etc/passwd | awk -F ":" '{print $1}'
Det här exemplet visar endast användarnamn (första fältet) eftersom avgränsaren nu är :Om du även vill ha UID och GID (fält 3 och 4), gör du helt enkelt följande:
cat /etc/passwd | awk -F ":" '{print $1, $3, $4}'
Problemet med det här kommandot är att utdata sitter ihop. Om du inte definierar explicita avgränsare kan du lägga till mellanslag eller tabb manuellt:
cat /etc/passwd | awk -F ":" '{print $1 " " $3 " " $4}'
Om du vill ha ett mer tabellerat resultatdu kan använda \t för att infoga tabbar:
cat /etc/passwd | awk -F ":" '{print $1 "\t" $3 "\t" $4}'
Alternativet med FS i ett BEGIN-block Det låter dig ställa in separatorn i själva awk-skriptet:
cat /etc/passwd | awk 'BEGIN { FS=":" } {print $1 "\t" $3 "\t" $4}'
Båda metoderna är funktionellt likvärdigaäven om man använder BEGIN {FS=...} Det är oftast renare när du skriver återanvändbara .awk-skript.
FS och OFS: ingångs- och utgångsseparatorer
Förutom FS (Field Separator) har awk OFS (Output Field Separator)vilket definierar hur fälten separeras när du använder print med kommatecken:
cat /etc/passwd | awk 'BEGIN { FS=":"; OFS=" - " } {print $1, $3, $4}'
I det här fallet läser du med : men du skriver med - , genererar en utdata som:
root - 0 - 0
daemon - 1 - 1
...
Denna FS/OFS-kombination är mycket användbar för att "omformatera" dataTill exempel för att konvertera från ett format till ett annat eller för att förbereda läsbara utdata som du sedan exporterar till ett annat system.
Hämta det sista fältet med $NF (och de föregående)
I många kommandoutdataFältet du är intresserad av finns i slutet, men det exakta antalet kolumner varierar. Det är där $NF (Antal fält) förenklar ditt liv: det är alltid det sista fältet på den aktuella raden.
Till exempel i /etc/shells Giltiga skalsökvägar visas i slutet av varje radIbland i den andra kolumnen, ibland i den tredje, etc. För att bara skriva ut skalnamnet (delen efter det sista snedstrecket):
awk -F "/" '/^\// {print $NF}' /etc/shells
Om du sedan bara vill behålla unika värden (utan dubbletter) kan du kedja med uniq:
awk -F "/" '/^\// {print $NF}' /etc/shells | uniq
Och om det som intresserar dig är den näst sista delen av vägen (till exempel den föregående katalogen) kan du använda $(NF-1) o $(NF-2):
awk -F "/" '/^\// {print $(NF-1)}' /etc/shells
awk -F "/" '/^\// {print $(NF-2)}' /etc/shells
Filtrera linjer med mönster, längd och logiska villkor
Awk lyser när du bara vill hålla dig till vissa rader baserat på textmönster, specifika kolumner eller numeriska villkor. Kombinera reguljära uttryck, logiska operatorer och funktioner som length för att göra mycket exakta filter.
Filtrera efter mönster och reguljära uttryck
Det mest direkta sättet att filtrera efter innehåll är att placera det reguljära uttrycket mellan snedstreck. Strax före tangenterna:
awk '/patrón/ {print}' archivo.txt
Till exempel, med avgången av df Du kan bara visa rader som börjar med ett snedstreck (monterade filsystem):
df | awk '/^\// {print}'
Om du vill ha en specifik partition, till exempel /dev/sda5:
df | awk '/^\/dev\/sda5/ {print}'
Du kan också filtrera efter mönster i början eller slutet av raden med ^ y $:
awk '/^tmpfs/ {print}' archivo.txt
awk '/\/shm$/ {print}' archivo.txt
Och kombinera flera kriterier med den logiska operatorn &&Till exempel rader som börjar med tmpfs och slutar i /dev/shm:
df | awk '/\/shm$/ && /^tmpfs/ {print}'
Filtrera efter kolumner och visa bara det som intresserar dig
Ofta vill man filtrera inte bara rader, utan även kolumner.Fortsätter med df -h, du kan bara visa riktiga filsystem (^/) och behåll sedan kolumnerna 1, 2 och 3:
df -h | awk '/^\// {print $1 "\t" $2 "\t" $3}'
Med Awk kan du till och med arbeta med fält i realtidLägg till exempel till kolumnerna 2 och 3 (använd + tillgänglig) för att se en beräknad "total kapacitet":
df -h | awk '/^\// {print $1 "\t" $2 + $3}'
Om du vill lägga till den bokstavliga enheten "G" i slutet av resultatet:
df -h | awk '/^\// {print $1 "\t" $2 + $3 "G"}'
Filtrera efter radlängd med hjälp av length()
Funktionen length() mäter antalet tecken i en strängDen används normalt med $0 (hel rad), men du kan också använda den med en specifik kolumn.
För att bara visa raderna av /etc/shells med fler än 9 tecken:
awk 'length($0) > 9' /etc/shells
Om du vill se längden på varje rad:
awk '{print length, "\t", $0}' /etc/shells
Du kan också filtrera efter längd och sedan bara skriva ut längden.:
awk 'length($0) > 9 {print length}' /etc/shells
Kombinera flera villkor med && och if
Förutom att använda reguljära uttryck i börjanDu kan skriva fullständiga villkor inom blocket med hjälp av if, jämförelse och logiska operatorer.
Till exempel, att bara visa rader av df -h som börjar med t och vars kolumn 6 har fler än 8 tecken:
df -h | awk '/^t/ && length($6) > 8 {print $0}'
Ett annat typiskt fall är att söka efter processer via det sista fältet (kommando körs) vid utgången av ps -efDet sista fältet är $NFSå du kan använda:
ps -ef | awk '{ if ($NF == "firefox") print $0 }'
Om du bara bryr dig om PID och kommandot:
ps -ef | awk '{ if ($NF == "firefox") print $2, $NF }'
Kontrolllinjer med NR, intervall och fältlängd
Variabeln NR (Number of Record) Den räknar hur många rader som har lästs hittills (globalt). Detta möjliggör vanliga saker som att hoppa över rubriker, skriva ut specifika radintervall eller bara visa den första raden.
Räkna rader och visa endast den första eller andra
Att räkna det totala antalet rader i en fil oanvänt wc -l Du kan göra:
awk 'END {print NR}' archivo.txt
Om du bara vill skriva ut den första raden:
awk 'NR==1 {print}' archivo.txt
Och för att bara visa den andra raden:
awk 'NR==2 {print}' archivo.txt
Skriv ut från en specifik rad eller ett specifikt område
För att visa alla rader från den tredje och framåt Du kan använda ett enkelt villkor med > o >=:
ps -aux | awk 'NR>2 {print}'
Om du vill ha ett intervall, till exempel raderna 2 till 4 en /etc/shells:
cat /etc/shells | awk 'NR==2, NR==4 {print $0}'
Du kan också skriva radnumret bredvid innehållet:
cat /etc/shells | awk 'NR==2, NR==4 {print NR, $0}'
Längden på specifika fält
Förutom att mäta längden på kompletta linjerDu kan kontrollera längden på en specifik kolumn. Till exempel, för att se hur många tecken filsystemet (kolumn 1) har i utdata från df -h:
df -h | awk '{print length($1) "\t" $1}'
Om du vill hoppa över rubriken (första raden), tillägger NR>1:
df -h | awk 'NR>1 {print length($1) "\t" $1}'
Användbara funktioner: substr, match, RSTART och RLENGTH
Awk innehåller ett bra utbud av textfunktionerTvå av de mest kraftfulla för avancerade sökningar är substr y match, den senare åtföljd av variablerna RSTART y RLENGTH.
Trimma text med substr()
Funktionen substr(cadena, inicio) o substr(cadena, inicio, longitud) Den låter dig extrahera delsträngar. Till exempel, för att ta bort de första 5 tecknen från varje rad av /etc/shells:
cat /etc/shells | awk '{print substr($0, 5)}'
Om du inte vill bearbeta den första raden (till exempel en kommentar) kan du använda NR:
cat /etc/shells | awk 'NR>1 {print substr($0, 5)}'
Observera att den första parametern är strängen (vanligtvis $0) och den andra anger vilket tecken du vill börja visa.
Hitta mönster med match(), RSTART och RLENGTH
Funktionen match(cadena, /regex/) sök efter ett reguljärt uttryck i strängenOm en matchning hittas returneras startpositionen (baserat på 1) och två variabler fylls i:
RSTART: position där det funna mönstret börjar.RLENGTH: matchens längd.
Till exempel för alla linjer av ps -aux som innehåller "cpu"Du kan visa hela linjen och positionen där mönstret finns:
ps -aux | awk 'match($0, /cpu/) {print $0 " Contiene \"cpu\" en la posición " RSTART}'
Om du också vill veta måtten på det hittade mönstret, använd bara RLENGTH vid utgången:
ps -aux | awk 'match($0, /cpu/) {print $0 " Posición=" RSTART " Longitud=" RLENGTH}'
Denna typ av sökning används ofta inom textanalys och bioinformatikTill exempel på FASTA-filer, där du är intresserad av att lokalisera specifika motiv i sekvenser.
Matematiska operationer och variabler i awk
Awk är inte begränsat till att visa text: låter dig utföra numeriska operationer direkt på fält, interna variabler eller värden som du skickar från kommandoraden eller från shell-miljön.
Definiera variabler med -vy och använd dem i BEGIN
Du kan deklarera variabler med alternativet -v när man anropar awkTill exempel, multiplicera två fasta tal:
awk -v a="10" -v b="20" 'BEGIN {print "La multiplicación de a x b es", a*b}'
Det är också möjligt att skicka variabla värden från ditt skalOm du gör det i bash:
a=1.5
b=4
Sedan kan du använda dem på ett konstigt sätt som det här:
awk -v a="$a" -v b="$b" 'BEGIN {print "La multiplicación de a x b es", a*b}'
BEGIN-blocket används här eftersom vi inte bearbetar någon fil.Vi vill bara köra koden en gång och visa ett resultat.
Matematiska funktioner: sqrt och for-loopar
Awk innehåller flera matematiska standardfunktioner.Som sqrt() för kvadratrötter. Till exempel, kvadratroten ur 400:
awk 'BEGIN {print sqrt(400)}'
Du kan också kombinera det med for loopar för att generera kompletta listor:
awk 'BEGIN { for(i=1; i<=10; i++) print "La raíz cuadrada de", i*i, "es", i }'
Eller gå igenom decimalvärden från 0 till 1 i små steg:
awk 'BEGIN { for(i=0; i<=1; i=i+0.00001) print "La raíz cuadrada de", i*i, "es", i }'
Den här typen av strukturer gör att awk är väldigt likt ett traditionellt språk.även om dess naturliga livsmiljö förblir kolumnformatet.
Att skriva och köra kompletta skript i awk
När awk-kommandon börjar bli långa Om du vill återanvända komplexa transformationer är det klokt att spara dem i en skriptfil med tillägget . .awk (även om det inte är obligatoriskt).
Ett typiskt exempel innebär att bearbeta utdata från df för att endast visa vissa poster som uppfyller villkoren för tillgängligt utrymme och formatera resultaten som en liten tabell.
Tänk dig att du vill ha följande:
- Visa endast filsystem vars namn börjar med "t" (till exempel
tmpfs). - Filtrera de med tillgänglig kapacitet (kolumn 4) större än 6000K.
- Skriv endast ut enheten (kolumn 1) och summan av kolumnerna 2 och 3 som ett ungefärligt totalt utrymme.
Du kan skapa ett skript som heter capacidad.awk med liknande innehåll som detta (anpassad och förenklad):
#!/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"}
Och sedan köra det genom att kedjekoppla utdata från df.:
df | awk -f capacidad.awk
Om du vill förbättra bordets utseende, kan du ersätta print av printf och använda format som %-12s (vänsterjusterad text på 12 tecken) eller %-23d (Decimaltal med 23 tecken). Detta ger dig perfekt kontroll över kolumnjusteringen.
Hitta och ersätt text med gsub()
Awk kan också utföra textersättningar liknande vad du skulle göra med sed, med hjälp av funktionen gsub() (global ersättning).
Den allmänna syntaxen är:
gsub("texto_o_regex_a_buscar", "texto_de_reemplazo", destino)
Anta till exempel en fil geekland.txt med texten ”Geekland är den bästa teknikbloggen” och du vill ändra det initiala G:et till g:
awk '{ gsub("G", "g", $0); print $0 }' geekland.txt
Om du inte anger den tredje parametern utförs sökningen på $0 som standardDet är dock mycket vanligt att begränsa ersättningen till en enda kolumn:
df -h | awk '{ gsub("M", "G", $2); print $2 }'
I det här fallet ändrade vi bara enheten M till G i kolumn 2.Om du även vill visa kolumn 1 korrekt justerad kan du kombinera den med printf:
df -h | awk '{ gsub("M", "G", $2); printf "%-12s %-12s\n", $1, $2 }'
Detta mönster av "Jag ändrar en kolumn och skriver sedan ut formaterad" Det är extremt användbart i rapporter, datamigreringar eller snabb rensning av kommandoutdata.
Ytterligare användningsområden: steroidinfekterad katt och kommandokörning
Även om det kan verka dumtawk kan fungera som cat Förbättrat, eftersom det kan visa en fil samtidigt som extra information läggs till (radnummer, längder etc.).
En trivial användning skulle vara:
awk '{print}' functions.php
Men du kan också numrera linjer eller använda valfritt filter. utan att behöva använda några ytterligare verktyg.
Ett annat intressant faktum är att awk kan köra systemkommandon med hjälp av funktionen system()Till exempel, för att visa den aktuella katalogen:
awk 'BEGIN { system("pwd") }'
Detta är inte den vanligaste metoden i enkla skript.Men det är bra att veta att det existerar när du bygger mer komplexa verktyg baserade på awk.
Awk blir en schweizisk armékniv för text i LinuxDet låter dig filtrera rader, välja och kombinera kolumner, ersätta fragment, mäta längder, hitta mönster, summera fält, generera småformaterade rapporter och till och med bygga kompletta skript som bearbetar utdata från andra kommandon. När du väl fått kläm på det blir det ett viktigt verktyg när du arbetar med... terminala och strukturerad data.
Passionerad författare om bytesvärlden och tekniken i allmänhet. Jag älskar att dela med mig av min kunskap genom att skriva, och det är vad jag kommer att göra i den här bloggen, visa dig alla de mest intressanta sakerna om prylar, mjukvara, hårdvara, tekniska trender och mer. Mitt mål är att hjälpa dig att navigera i den digitala världen på ett enkelt och underhållande sätt.