Komplet awk-tutorial til Linux: en praktisk trin-for-trin-guide

Sidste ændring: 15/12/2025
Forfatter: Isaac
  • awk er et værktøj og scriptsprog orienteret mod tekstbehandling med linjer og kolonner, ideelt til filtrering, transformation og analyse af output fra kommandoer og filer.
  • Det giver dig mulighed for at definere mønstre og handlinger ved at kombinere regulære udtryk, specielle variabler som $0, $1, NF eller NR, og funktioner som længde, substr eller match for at lave meget præcise filtre.
  • awk fungerer komfortabelt med afgrænsere og felter ved hjælp af FS, OFS og indstillinger som -F, og kan format output med print og printf, udfør matematiske operationer og administrer variabler med -v.
  • Det er muligt at oprette komplette awk-scripts, der automatiserer komplekse opgaver, herunder søgninger og erstatninger med gsub, avancerede beregninger og generering af rapporter fra kommandoer som ps, df eller systemfiler.

awk-tutorial om Linux

Når du begynder at tage konsollen seriøst Linux Du opdager, at arbejde med tekst ikke kun handler om at se på filer med cat Og det er stort set det. Så snart du kommer ind i logs Til enorme lister over processer, kommandooutput eller CSV-filer har du brug for noget meget mere kraftfuldt til at filtrere, transformere og opsummere data uden at gøre dig selv vanvittig.

Det er her, akavet kommer ind i billedet.en kommando, der mere end blot et simpelt filter, praktisk talt er et sprog for programmering Awk er et tekstbehandlingsværktøj, der giver dig mulighed for at søge efter mønstre, vælge kolonner, udføre beregninger, definere betingelser, bruge variabler, løkker, funktioner og endda skrive komplette scripts. I denne awk-tutorial til Linux udforsker vi det trin for trin, fra det grundlæggende til forholdsvis avancerede anvendelser, og inkorporerer alle mulige eksempler fra den virkelige verden på konsoller.

Hvad er awk, og hvad bruges det til i Linux?

Awk er både et kommandolinjeværktøj og et scriptsprog Det er designet til at analysere tekst struktureret i linjer og felter, og navnet stammer fra initialerne af dets skabere (Aho, Weinberger og Kernighan). Det har været i brug siden slutningen af ​​70'erne, men er fortsat en nøglekomponent i ethvert miljø. Unix eller GNU/Linux (for eksempel Kør den gamle Unix på din pc).

Filosofien bag awk er meget enkelItererer gennem en fil (eller outputtet fra en kommando) linje for linje, opdeler hver linje i kolonner i henhold til en separator, kontrollerer om en betingelse er opfyldt, og udfører i så fald en handling. Hvis du ikke angiver en betingelse, anvendes handlingen på alle linjer; hvis du ikke angiver en handling, er standardhandlingen at udskrive hele linjen.

Med denne simple mekanisme kan du gøre virkelig vanvittige ting.: fra kun at vise nogle kolonner af ps o df...til at beregne totaler, filtrere efter komplekse mønstre med regulære udtryk, erstatte tekst, formatere rapporter, arbejde med CSV-filer eller endda skrive scripts på flere dusin linjer.

Selvom awk måske minder dig lidt om grep eller sedDens tilgang er mere struktureret: tænk på linjer som poster og ord (eller felter) som kolonner, med interne variabler og et minisprog, der gør den ideel til hurtig behandling af tabeldata.

I praksis, hvis du vil begynde at skrive ordentlige shell-scripts...Det er næsten obligatorisk at kende awk sammen med andre værktøjer som f.eks. sed, grep, cut og virksomhed. De er de grundlæggende byggesten i tekstbehandling i Linux.

Installer og kør awk (gawk) på dit system

I de fleste moderne GNU/Linux-distributionerawk er allerede installeret som standard, normalt i GNU awk-varianten (gawkDu kan tjekke det med:

awk --version

Hvis du af en eller anden grund ikke har det installeretI Debian, Ubuntu og derivater kan du bruge pakkehåndteringen:

sudo apt update && sudo apt install gawk

Den er også tilgængelig på macOS.Du kan bruge systemversionen eller installere en opdateret version med Homebrew:

brew install gawk

Når awk er installeret, bruges den altid med den samme idé.Du sender instruktioner mellem enkelte anførselstegn og en fil (eller sender outputtet fra en anden kommando via pipe-links). For eksempel:

awk '{print}' archivo.txt

Du kan også bruge awk som en scriptfortolker, der angiver stien til den eksekverbare fil i filens første linje:

#!/usr/bin/awk -f

og derefter kører script direkte eller med awk -f script.awk.

Grundlæggende syntaks: mønstre og handlinger

Brug af awk i terminalen

Den minimale struktur af awk er:

awk 'patrón { acción }' fichero

Hver linje i filen sammenlignes med mønsteret.Hvis det matcher, udføres handlingen inden for de krøllede parenteser. Hvis du udelader mønsteret, anvendes handlingen på alle linjer. Nogle vigtige ideer:

Specielle variabler, der refererer til hver linje:

  • $0: den komplette linje.
  • $1, $2, $3, …: felter (kolonner) på linjen, adskilt af den definerede afgrænser.
  • NFantallet af felter i den aktuelle linje.
  • NR: nuværende registreringsnummer (globalt linjenummer).
  • FNRlinjenummer i den aktuelle fil, nyttigt ved behandling af flere filer.

Særlige instruktioner:

  • BEGIN { … }: blok der udføres før en linje læses.
  • END { … }: blok, der udføres efter behandling af alle linjer.

De mest almindelige outputkommandoer:

  • print: udskriver argumenter adskilt af outputseparatoren (OFS(som standard et mellemrum).
  • printf: ligner printf I C tillader den detaljeret formatering uden at tilføje automatiske linjeskift.
  Sådan aktiveres og foretages videoopkald på Instagram ved hjælp af din telefon eller pc

Minimalt eksempel på udskrivning af en fil præcis som den er, som om den var cat:

awk '{print}' archivo.txt

Eller hvis du også vil have længden af ​​hver linje vist:

awk '{print length, "\t", $0}' archivo.txt

Arbejde med kolonner og separatorer i awk

En af awks bedste anvendelser er at manipulere kolonner fra kommandooutput som f.eks. ps, df eller filer som /etc/passwdSom standard betragter awk ethvert mellemrum eller tabulator som en separator, men du kan bruge stort set enhver afgrænser.

Vælg specifikke kolonner

Forestil dig udgangen af ps med flere kolonner (PID, TTY, TIME, CMD…)Hvis du kun vil se PID'erne, skal du blot:

ps | awk '{print $1}'

Hvis du er interesseret i den anden kolonne (for eksempel TTY):

ps | awk '{print $2}'

Og hvis du vil springe den første linje (overskriften) overDu kan filtrere efter registreringsnummer:

ps | awk 'NR>1 {print $1}'

Ideen er meget enkel.hvert tal efter symbolet $ Den refererer til den tilsvarende kolonne, altid i forhold til den aktuelle separator.

Skift afgrænseren med -F og med FS

Mange systemfiler er ikke adskilt af mellemrum.men af ​​andre symbolerEn klassiker er /etc/passwdhvor felterne er adskilt af :For at behandle filen efter kolonner har du to muligheder: muligheden -F på kommandolinjen eller variablen FS inde i en blok BEGIN.

Brug af -F på kommandolinjen:

cat /etc/passwd | awk -F ":" '{print $1}'

Dette eksempel viser kun brugernavne (første felt) fordi separatoren nu er :Hvis du også ønsker UID og GID (felt 3 og 4), skal du blot:

cat /etc/passwd | awk -F ":" '{print $1, $3, $4}'

Problemet med denne kommando er, at outputtet hænger sammen. Hvis du ikke definerer eksplicitte separatorer, kan du tilføje mellemrum eller tabulatorer manuelt:

cat /etc/passwd | awk -F ":" '{print $1 " " $3 " " $4}'

Hvis du ønsker et mere tabelformet resultatdu kan bruge \t at indsætte faner:

cat /etc/passwd | awk -F ":" '{print $1 "\t" $3 "\t" $4}'

Alternativet med FS i en BEGIN-blok Det giver dig mulighed for at indstille separatoren i selve awk-scriptet:

cat /etc/passwd | awk 'BEGIN { FS=":" } {print $1 "\t" $3 "\t" $4}'

Begge tilgange er funktionelt ækvivalenteselvom man bruger BEGIN {FS=...} Det er normalt mere overskueligt, når du skriver genbrugelige .awk-scripts.

FS og OFS: input- og outputseparatorer

Udover FS (Field Separator) har awk OFS (Output Field Separator)som definerer, hvordan felterne er adskilt, når du bruger print med kommaer:

cat /etc/passwd | awk 'BEGIN { FS=":"; OFS=" - " } {print $1, $3, $4}'

I dette tilfælde læser du med : men du skriver med - , genererer et output som:

root - 0 - 0
daemon - 1 - 1
...

Denne FS/OFS-kombination er meget nyttig til "omformatering" af dataFor eksempel at konvertere fra ét format til et andet eller at forberede læsbare output, som du derefter eksporterer til et andet system.

Hent det sidste felt med $NF (og de foregående)

I mange kommandooutputDet felt, du er interesseret i, er til sidst, men det præcise antal kolonner varierer. Det er der $NF (Antal felter) forenkler dit liv: det er altid det sidste felt i den aktuelle linje.

For eksempel i /etc/shells Gyldige shell-stier vises i slutningen af ​​hver linjeNogle gange i den anden kolonne, nogle gange i den tredje osv. For kun at udskrive shell-navnet (den del, der er efter den sidste skråstreg):

awk -F "/" '/^\// {print $NF}' /etc/shells

Hvis du derefter kun vil beholde unikke værdier (uden dubletter), kan du kæde sammen med uniq:

awk -F "/" '/^\// {print $NF}' /etc/shells | uniq

Og hvis det, der interesserer dig, er det næstsidste element på stien (for eksempel den forrige mappe), kan du bruge $(NF-1) o $(NF-2):

awk -F "/" '/^\// {print $(NF-1)}' /etc/shells

awk -F "/" '/^\// {print $(NF-2)}' /etc/shells

Filtrer linjer med mønstre, længde og logiske betingelser

Awk er effektiv, når du kun vil holde dig til bestemte rækker baseret på tekstmønstre, specifikke kolonner eller numeriske betingelser. Kombiner regulære udtryk, logiske operatorer og funktioner som f.eks. length at lave meget præcise filtre.

Filtrer efter mønstre og regulære udtryk

Den mest direkte måde at filtrere efter indhold er at placere det regulære udtryk mellem skråstreger. Lige før tasterne:

awk '/patrón/ {print}' archivo.txt

For eksempel med afgangen af df Du kan kun vise linjer, der starter med en skråstreg (monterede filsystemer):

df | awk '/^\// {print}'

Hvis du ønsker en specifik partition, f.eks. /dev/sda5:

df | awk '/^\/dev\/sda5/ {print}'

Du kan også filtrere efter mønstre i begyndelsen eller slutningen af ​​linjen hjælp ^ y $:

awk '/^tmpfs/ {print}' archivo.txt
awk '/\/shm$/ {print}' archivo.txt

Og kombiner flere kriterier med den logiske operator &&For eksempel linjer, der starter med tmpfs og slutter i /dev/shm:

df | awk '/\/shm$/ && /^tmpfs/ {print}'

Filtrer efter kolonner og vis kun det, der interesserer dig

Ofte vil du filtrere ikke kun rækker, men også kolonner.Fortsætter med df -h, du kan kun vise rigtige filsystemer (^/) og behold derefter kolonne 1, 2 og 3:

  Komplet guide til at mestre powercfg-kommandoen i Windows

df -h | awk '/^\// {print $1 "\t" $2 "\t" $3}'

Awk giver dig endda mulighed for at arbejde med felter på fartenFor eksempel kan du lægge kolonne 2 og 3 (brugt + tilgængelig) sammen for at se en beregnet "samlet kapacitet":

df -h | awk '/^\// {print $1 "\t" $2 + $3}'

Hvis du vil tilføje den bogstavelige enhed "G" til slutningen af ​​resultatet:

df -h | awk '/^\// {print $1 "\t" $2 + $3 "G"}'

Filtrer efter linjelængde ved hjælp af length()

Funktionen length() måler antallet af tegn i en strengDet bruges normalt med $0 (fuld linje), men du kan også bruge den med en bestemt kolonne.

For kun at vise linjerne fra /etc/shells med mere end 9 tegn:

awk 'length($0) > 9' /etc/shells

Hvis du vil se længden af ​​hver linje:

awk '{print length, "\t", $0}' /etc/shells

Du kan også filtrere efter længde og derefter kun udskrive længden.:

awk 'length($0) > 9 {print length}' /etc/shells

Kombinér flere betingelser med && og hvis

Udover at bruge regulære udtryk i begyndelsenDu kan skrive komplette betingelser inden for blokken ved hjælp af if, sammenligning og logiske operatorer.

For eksempel, visning kun linjer af df -h der begynder med t og hvis kolonne 6 har mere end 8 tegn:

df -h | awk '/^t/ && length($6) > 8 {print $0}'

Et andet typisk tilfælde er at søge efter processer via det sidste felt (kommando udført) ved outputtet af ps -efDet sidste felt er $NFSå du kan bruge:

ps -ef | awk '{ if ($NF == "firefox") print $0 }'

Hvis du kun er interesseret i PID'en og kommandoen:

ps -ef | awk '{ if ($NF == "firefox") print $2, $NF }'

Kontrollinjer med NR, intervaller og feltlængde

NR-variablen (antal poster) Den tæller, hvor mange linjer der er blevet læst indtil videre (globalt). Dette giver mulighed for almindelige ting som at springe overskrifter over, udskrive specifikke linjeintervaller eller kun vise den første række.

Tæl linjer og vis kun den første eller anden

Sådan tæller du det samlede antal linjer i en fil ubrugt wc -l Du kan gøre:

awk 'END {print NR}' archivo.txt

Hvis du kun vil udskrive den første linje:

awk 'NR==1 {print}' archivo.txt

Og for kun at vise den anden linje:

awk 'NR==2 {print}' archivo.txt

Udskriv startende fra en bestemt linje eller et bestemt område

For at vise alle linjer fra den tredje og fremefter Du kan bruge en simpel betingelse med > o >=:

ps -aux | awk 'NR>2 {print}'

Hvis du ønsker et interval, for eksempel linje 2 til 4 en /etc/shells:

cat /etc/shells | awk 'NR==2, NR==4 {print $0}'

Du kan også udskrive linjenummeret ved siden af ​​indholdet:

cat /etc/shells | awk 'NR==2, NR==4 {print NR, $0}'

Længden af ​​specifikke felter

Ud over at måle længden af ​​komplette linjerDu kan kontrollere længden af ​​en bestemt kolonne. For eksempel for at se, hvor mange tegn filsystemet (kolonne 1) har i outputtet af df -h:

df -h | awk '{print length($1) "\t" $1}'

Hvis du vil springe overskriften over (første linje), tilføjer NR>1:

df -h | awk 'NR>1 {print length($1) "\t" $1}'

Nyttige funktioner: substr, match, RSTART og RLENGTH

Awk indeholder et godt udvalg af tekstfunktionerTo af de mest effektive til avanceret søgning er substr y match, sidstnævnte ledsaget af variablerne RSTART y RLENGTH.

Beskær tekst med substr()

Funktionen substr(cadena, inicio) o substr(cadena, inicio, longitud) Det giver dig mulighed for at udtrække delstrenge. For eksempel, for at fjerne de første 5 tegn fra hver linje af /etc/shells:

cat /etc/shells | awk '{print substr($0, 5)}'

Hvis du ikke vil behandle den første linje (for eksempel en kommentar), kan du bruge NR:

cat /etc/shells | awk 'NR>1 {print substr($0, 5)}'

Bemærk at den første parameter er strengen (normalt $0) og den anden angiver hvilket tegn du vil begynde at vise.

Find mønstre med match(), RSTART og RLENGTH

Funktionen match(cadena, /regex/) søg efter et regulært udtryk i strengenHvis der findes et match, returneres startpositionen (baseret på 1) og to variabler udfyldes:

  • RSTART: position hvor det fundne mønster begynder.
  • RLENGTH: kampens længde.

For eksempel for alle linjer af ps -aux der indeholder "cpu"Du kan vise hele linjen og den position, hvor mønsteret er placeret:

ps -aux | awk 'match($0, /cpu/) {print $0 " Contiene \"cpu\" en la posición " RSTART}'

Hvis du også vil kende dimensionerne på det fundne mønster, bare brug RLENGTH ved udgangen:

ps -aux | awk 'match($0, /cpu/) {print $0 " Posición=" RSTART " Longitud=" RLENGTH}'

Denne type søgning bruges i vid udstrækning inden for tekstanalyse og bioinformatikFor eksempel på FASTA-filer, hvor du er interesseret i at finde specifikke motiver i sekvenser.

Matematiske operationer og variabler i awk

Awk er ikke begrænset til at vise tekstgiver dig mulighed for at udføre numeriske operationer direkte på felter, interne variabler eller værdier, som du sender fra kommandolinjen eller fra shell-miljøet.

  Sådan åbner og konverterer du PKPASS-filer i Windows

Definer variabler med -vy og brug dem i BEGIN

Du kan deklarere variabler med indstillingen -v når man aktiverer awkFor eksempel, multiplicering af to faste tal:

awk -v a="10" -v b="20" 'BEGIN {print "La multiplicación de a x b es", a*b}'

Det er også muligt at overføre variable værdier fra din shellHvis du gør det i bash:

a=1.5
b=4

Så kan du bruge dem i akavede situationer som denne:

awk -v a="$a" -v b="$b" 'BEGIN {print "La multiplicación de a x b es", a*b}'

BEGIN-blokken bruges her, fordi vi ikke behandler nogen fil.Vi vil bare køre koden én gang og vise et resultat.

Matematiske funktioner: sqrt og for-løkker

Awk inkorporerer adskillige standard matematiske funktioner.Som sqrt() for kvadratrødder. For eksempel kvadratroden af ​​400:

awk 'BEGIN {print sqrt(400)}'

Du kan også kombinere det med for loops for at generere komplette lister:

awk 'BEGIN { for(i=1; i<=10; i++) print "La raíz cuadrada de", i*i, "es", i }'

Eller gennemløb decimalværdier fra 0 til 1 i små trin:

awk 'BEGIN { for(i=0; i<=1; i=i+0.00001) print "La raíz cuadrada de", i*i, "es", i }'

Disse typer strukturer gør awk meget lig et traditionelt sprogselvom dens naturlige habitat forbliver kolonneformatet.

Skrive og køre komplette scripts i awk

Når awk-kommandoer begynder at blive lange Hvis du vil genbruge komplekse transformationer, er det fornuftige at gemme dem i en scriptfil med filtypen . .awk (selvom det ikke er obligatorisk).

Et typisk eksempel involverer behandling af outputtet fra df for kun at vise bestemte poster, der opfylder betingelserne vedrørende tilgængelig plads, og formatere resultaterne som en lille tabel.

Forestil dig, at du ønsker følgende:

  • Vis kun filsystemer, hvis navn starter med "t" (f.eks tmpfs).
  • Filtrer dem med tilgængelig kapacitet (kolonne 4) større end 6000K.
  • Udskriv kun enheden (kolonne 1) og summen af ​​kolonne 2 og 3 som et omtrentligt samlet rum.

Du kan oprette et script kaldet capacidad.awk med indhold der ligner dette (tilpasset og forenklet):

#!/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"}

Og udfør det derefter ved at kæde outputtet fra df sammen.:

df | awk -f capacidad.awk

Hvis du vil forbedre bordets udseende, kan du erstatte print af printf og bruge formater som %-12s (venstrejusteret tekst på 12 tegn) eller %-23d (Decimaltal på 23 tegn). Dette giver dig perfekt kontrol over kolonnejustering.

Find og erstat tekst med gsub()

Awk kan også udføre tekstudskiftninger svarende til hvad du ville gøre med sed, ved at bruge funktionen gsub() (global erstatning).

Den generelle syntaks er:

gsub("texto_o_regex_a_buscar", "texto_de_reemplazo", destino)

Antag for eksempel en fil geekland.txt med teksten "Geekland er den bedste tech-blog", og du vil ændre det indledende G til g:

awk '{ gsub("G", "g", $0); print $0 }' geekland.txt

Hvis du ikke angiver den tredje parameter, udføres søgningen på $0 som standardDet er dog meget almindeligt at begrænse erstatningen til en enkelt kolonne:

df -h | awk '{ gsub("M", "G", $2); print $2 }'

I dette tilfælde ændrede vi kun enheden M til G i kolonne 2.Hvis du også vil have kolonne 1 korrekt justeret, kan du kombinere den med printf:

df -h | awk '{ gsub("M", "G", $2); printf "%-12s %-12s\n", $1, $2 }'

Dette mønster af "Jeg ændrer en kolonne og udskriver derefter formateret" Det er yderst nyttigt i rapporter, datamigreringer eller hurtig oprydning af kommandooutput.

Yderligere anvendelser: steroidinficeret kat og kommandoudførelse

Selvom det kan virke fjolletawk kan fungere som cat Forbedret, da den kan vise en fil, mens den tilføjer ekstra information (linjenumre, længder osv.).

En triviel anvendelse ville være:

awk '{print}' functions.php

Men du kan også nummerere linjer eller anvende et hvilket som helst filter. uden at skulle bruge yderligere værktøjer.

En anden interessant kendsgerning er, at awk kan udføre systemkommandoer ved hjælp af funktionen system()For eksempel, for at vise den aktuelle mappe:

awk 'BEGIN { system("pwd") }'

Dette er ikke den mest almindelige praksis i simple scripts.Men det er godt at vide, at det findes, når du bygger mere komplekse værktøjer baseret på awk.

Awk bliver en schweizerkniv til tekst i LinuxDet giver dig mulighed for at filtrere rækker, vælge og kombinere kolonner, erstatte fragmenter, måle længder, finde mønstre, summere felter, generere små formaterede rapporter og endda bygge komplette scripts, der behandler outputtet fra andre kommandoer. Når du først har fået styr på det, bliver det et vigtigt værktøj, når du arbejder med... terminal og strukturerede data.

Kør Ancient Unix-vejledning
relateret artikel:
Sådan kører du ældre UNIX-systemer på din pc: SIMH, Docker, V7/V8, BSD og mere