Az awk segítségével összegezhetünk egy oszlop értékét egy másik oszlop értéke alapján

Megpróbálok egyes oszlopban lévő számokat összegezni a awk. Csak a “kovácsok” 3. oszlopát szeretném összefoglalni, hogy összesen 212-et kapjak. Az egész oszlopot összegezhetem a awk felhasználásával, de nem csak a “kovácsokat”. Nekem van:

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

Én is gittet használok. Köszönöm a segítséget.

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

Válasz

awk -F "|" "$1 ~ /smiths/ {sum += $3} END {print sum}" inputfilename 
  • A -F zászló beállítja a mezőelválasztót; Egyetlen idézőjelbe tettem, mert ez egy különleges shell karakter.
  • Ekkor a $1 ~ /smiths/ csak a következő kódkódot alkalmazza azokra a sorokra, ahol az első mező megegyezik a /smiths/ regexszel.
  • A többi megegyezik a kódoddal.

Ne feledje, hogy mivel itt nem használsz regexet, csak egy adott értéket, ugyanolyan könnyen use:

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

Ez ellenőrzi a karakterlánc egyenlőségét. Ez egyenértékű a /^smiths$/ regex használatával, amint azt egy másik válasz, amely a ^ horgonyt tartalmazza, hogy csak a karakterlánc kezdetével (az 1. mező kezdete) és a $ horgonccal illeszkedjen illeszkedjen a karakterlánc végéhez. Nem biztos abban, hogy mennyire ismeri a regexeket. Nagyon hatékonyak, de ebben az esetben ugyanolyan egyszerűen használhatja a karakterlánc-egyenlőség-ellenőrzést.

Megjegyzések

  • Egyébként a kedvenc awk hivatkozásom a grymoire.com/Unix/Awk.html . Nagyon hasznos oldal .
  • Köszönöm @ Wildcard! A tanácsaid alapján szépen össze tudtam tömöríteni az egyes fájlok méretét a nagy zip archívumban 🙂

Válasz

Egy másik megközelítés az awk asszociatív tömbök használata, további információ itt . Ez a sor hozza létre a kívánt kimenetet:

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

Mellékhatásként a tömb tárolja az összes többi értéket:

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

Kimenet:

smiths 212 denniss 100 olivert 10 

Megjegyzések

  • Ez a helyes válasz

Válasz

Eddig nagyon jó. Csak annyit kell tennie, hogy hozzáad egy választót a blokk elé az összeg hozzáadásához. Itt ellenőrizzük, hogy az első argumentum csak “kovácsokat” tartalmaz-e:

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

Ezt kissé lerövidítheti a mezőelválasztó opcióként történő megadásával. A awk szakaszban általában jó ötlet a változók inicializálása a parancssorban:

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

Válasz

Én személy szerint legszívesebben a awk szakaszt tartanám a lehető legegyszerűbbnek, és csinálnék anélkül, amennyit csak lehet. . Az összeomlott logika nem használja ki a Unix csővezetékek erejét, ezért nehezebb megérteni, hibakeresni vagy módosítani a szorosan kapcsolódó felhasználási esetekhez.

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

Válasz

cat filename.txt | grep smiths | awk -F "|" "{sum+=$NF} END {print sum}" 
  • -F opció az elválasztó megadására .
  • $NF az “utolsó oszlop”.

Megjegyzések

  • cat és grep itt felesleges.
  • Miért nincs szükség a grep-re @Andrey? Az OP csak " kovács " sorokat akar hozzáadni. ' módosítania kell az awk utasítást, igaz?
  • @EL igen, az awk utasítást módosítani kell /smiths/{...} ha a grep hívás nincs meg. Ez egy triviális módosítás, de jelentős előnyökkel jár: csökkenti a futó folyamatok számát, egyszerűbbé teszi a hibakezelést és világosabbá teszi a kódot.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük