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
ésgrep
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.