Jeg prøver at summere bestemte tal i en kolonne ved hjælp af awk
. Jeg vil bare sammenfatte kolonne 3 i “smederne” for at få i alt 212. Jeg kan sammenfatte hele kolonnen ved hjælp af awk
men ikke kun “smederne”. Jeg har:
awk "BEGIN {FS = "|"} ; {sum+=$3} END {print sum}" filename.txt
Også jeg bruger kit. Tak for enhver hjælp.
smiths|Login|2 olivert|Login|10 denniss|Payroll|100 smiths|Time|200 smiths|Logout|10
Svar
awk -F "|" "$1 ~ /smiths/ {sum += $3} END {print sum}" inputfilename
-
-F
flag indstiller feltadskilleren; Jeg sætter det i enkelte citater, fordi det er en særlig skalkarakter. - Derefter anvender
$1 ~ /smiths/
følgende {kodeblok} kun på linjer, hvor det første felt matcher regex/smiths/
. - Resten er den samme som din kode.
Bemærk, at da du ikke rigtig bruger en regex her, bare en bestemt værdi, kan du lige så let brug:
awk -F "|" "$1 == "smiths" {sum += $3} END {print sum}" inputfilename
Hvilket kontrollerer strengens ligestilling. Dette svarer til at bruge regex /^smiths$/
, som nævnt i en anden svar, som inkluderer ^
anker for kun at matche starten af strengen (starten på felt 1) og $
ankeret til kun match slutningen af strengen. Ikke sikker på, hvor bekendt du er med regexes. De er meget kraftfulde, men i dette tilfælde kan du bruge en streng lighedskontrol lige så let.
Kommentarer
- Forresten er min favorit-awk-reference grymoire.com/Unix/Awk.html . Meget hjælpsom side .
- Tak @Wildcard! Jeg kunne pænt samle en ukomprimeret størrelse af bestemte filer i stort zip-arkiv baseret på dit råd 🙂
Svar
En anden tilgang er at bruge awk associative arrays, mere info her . Denne linje producerer det ønskede output:
awk -F "|" "{a[$1] += $3} END{print a["smiths"]}" filename.txt
Som en bivirkning gemmer arrayet alle andre værdier:
awk -F "|" "{a[$1] += $3} END{for (i in a) print i, a[i]}" filename.txt
Output:
smiths 212 denniss 100 olivert 10
Kommentarer
- Dette er det rigtige svar
Svar
Meget god indtil videre. Alt hvad du skal gøre er at tilføje en vælger inden blokken for at tilføje summen. Her kontrollerer vi, at det første argument kun indeholder “smede”:
awk "BEGIN {FS = "|"} ; $1 ~ /^smiths$/ {sum+=$3} END {print sum}"
Du kan forkorte dette en smule ved at angive feltadskilleren som en mulighed. I awk
er det generelt en god ide at initialisere variabler på kommandolinjen:
awk -F"|" "$1 ~ /^smiths$/ {sum+=$3} END {print sum}"
Svar
Jeg foretrækker personligt at holde sektionen awk
så enkel som muligt og gøre så meget som muligt uden det Comedled-logik udnytter ikke kraften i Unix-rørledninger og er derfor sværere at forstå, debugge eller ændre til nært beslægtede brugssager.
cat filename.txt | perl -pe "s{.*|}{}g" | awk "{sum+=$1} END {print sum}"
Svar
cat filename.txt | grep smiths | awk -F "|" "{sum+=$NF} END {print sum}"
-
-F
mulighed for at specificere separator . -
$NF
er til “sidste kolonne”.
Kommentarer
-
cat
oggrep
er unødvendige her. - Hvorfor er grep unødvendigt @Andrey? OP ønsker kun at tilføje " smiths " rækker. Du ' har brug for at ændre awk-sætningen, ikke?
- @EL ja, awk-sætningen skal ændres til
/smiths/{...}
hvis grep-opkaldet ikke er der. Dette er en triviel ændring, men det giver betydelige fordele: mindsker antallet af kørende processer, forenkler fejlkontrol og gør koden klarere.