Pomocí awk k součtu hodnot sloupce na základě hodnot jiného sloupce

Snažím se sečíst určitá čísla ve sloupci pomocí awk. Chtěl bych sečíst jen sloupec 3 „kovářů“, abych získal celkem 212. Celý sloupec mohu shrnout pomocí awk, ale nejen „kovářů“. Mám:

awk "BEGIN {FS = "|"} ; {sum+=$3} END {print sum}" filename.txt 

Také používám tmel. Děkujeme za jakoukoli pomoc.

smiths|Login|2 olivert|Login|10 denniss|Payroll|100 smiths|Time|200 smiths|Logout|10 

Odpověď

awk -F "|" "$1 ~ /smiths/ {sum += $3} END {print sum}" inputfilename 
  • Příznak -F nastavuje oddělovač polí; Dal jsem to do jednoduchých uvozovek, protože se jedná o speciální charakter shellu.
  • Potom $1 ~ /smiths/ použije následující {kódový blok} pouze na řádky, kde první pole odpovídá regulárnímu výrazu /smiths/.
  • Zbytek je stejný jako váš kód.

Všimněte si, že protože zde opravdu nepoužíváte regex, pouze konkrétní hodnotu, můžete stejně snadno use:

awk -F "|" "$1 == "smiths" {sum += $3} END {print sum}" inputfilename 

Který kontroluje rovnost řetězců. To odpovídá použití regex /^smiths$/, jak je uvedeno v jiném odpověď, která obsahuje ^ kotvu, která odpovídá pouze začátku řetězce (začátek pole 1), a $ kotvu pouze porovnejte konec řetězce. Nejste si jisti, jak dobře jste obeznámeni s regulárními výrazy. Jsou velmi silné, ale v tomto případě můžete stejně snadno použít kontrolu rovnosti řetězce.

Komentáře

  • Mimochodem, moje oblíbená reference awk je grymoire.com/Unix/Awk.html . Velmi užitečná stránka .
  • Děkuji vám @Wildcard! Na základě vaší rady jsem dokázal úhledně agregovat nekomprimovanou velikost konkrétních souborů ve velkém archivu zip 🙂

Odpověď

Dalším přístupem je použití awk asociativních polí, více informací zde . Tento řádek vytváří požadovaný výstup:

awk -F "|" "{a[$1] += $3} END{print a["smiths"]}" filename.txt 

Jako vedlejší efekt pole ukládá všechny ostatní hodnoty:

awk -F "|" "{a[$1] += $3} END{for (i in a) print i, a[i]}" filename.txt 

Výstup:

smiths 212 denniss 100 olivert 10 

Komentáře

  • Toto je správná odpověď

Odpověď

Zatím velmi dobrá. Vše, co musíte udělat, je přidat selektor před blok a přidat součet. Zde zkontrolujeme, zda první argument obsahuje pouze „kováře“:

awk "BEGIN {FS = "|"} ; $1 ~ /^smiths$/ {sum+=$3} END {print sum}" 

Tuto možnost můžete trochu zkrátit zadáním oddělovače polí jako možnosti. V awk je obecně dobrý nápad inicializovat proměnné na příkazovém řádku:

awk -F"|" "$1 ~ /^smiths$/ {sum+=$3} END {print sum}" 

Odpověď

Osobně bych raději udržoval sekci awk co nejjednodušší a bez ní dělal, co můžete, . Kombinovaná logika nevyužívá sílu unixových kanálů, a je proto těžší ji pochopit, ladit nebo upravit pro úzce související případy použití.

cat filename.txt | perl -pe "s{.*|}{}g" | awk "{sum+=$1} END {print sum}" 

Odpověď

cat filename.txt | grep smiths | awk -F "|" "{sum+=$NF} END {print sum}" 
  • -F možnost zadat oddělovač .
  • $NF je pro „poslední sloupec“.

Komentáře

  • cat a grep jsou zde zbytečné.
  • Proč je grep nepotřebný @Andrey? OP chce přidat pouze " smiths " řádky. Musíte ' upravit prohlášení awk, že?
  • @EL ano, prohlášení awk by mělo být upraveno na /smiths/{...} pokud tam není hovor grep. Toto je triviální úprava, ale přináší významné výhody: snižuje počet spuštěných procesů, zjednodušuje kontrolu chyb a činí kód jasnějším.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *