Încerc să sumez anumite numere dintr-o coloană folosind awk
. Aș dori să rezum doar coloana 3 din „smiths” pentru a obține un total de 212. Pot să însumez întreaga coloană folosind awk
, dar nu doar „smiths”. Am:
awk "BEGIN {FS = "|"} ; {sum+=$3} END {print sum}" filename.txt
De asemenea, folosesc chit. Vă mulțumim pentru ajutor.
smiths|Login|2 olivert|Login|10 denniss|Payroll|100 smiths|Time|200 smiths|Logout|10
Răspuns
awk -F "|" "$1 ~ /smiths/ {sum += $3} END {print sum}" inputfilename
- Steagul
-F
setează separatorul de câmp; Am pus-o în ghilimele unice, deoarece este un personaj special de tip shell. - Apoi
$1 ~ /smiths/
aplică următorul {bloc de cod} numai liniilor în care primul câmp corespunde regexului/smiths/
. - Restul este același cu codul dvs.
Rețineți că, din moment ce nu utilizați cu adevărat o regex aici, doar o anumită valoare, ați putea la fel de simplu use:
awk -F "|" "$1 == "smiths" {sum += $3} END {print sum}" inputfilename
Care verifică egalitatea șirurilor. Aceasta este echivalentă cu utilizarea regexului /^smiths$/
, așa cum se menționează într-un alt răspuns, care include ^
ancora pentru a se potrivi doar cu începutul șirului (începutul câmpului 1) și cu $
numai cu potriviți sfârșitul șirului. Nu sunteți sigur cât de familiarizați cu regexurile. Acestea sunt foarte puternice, dar pentru acest caz puteți utiliza o verificare a egalității șirurilor la fel de ușor.
Comentarii
- Apropo, referința mea preferată pentru awk este grymoire.com/Unix/Awk.html . Pagina foarte utilă .
- Vă mulțumim @Wildcard! Am reușit să cumulez cu grijă o dimensiune necomprimată a anumitor fișiere într-o arhivă zip mare pe baza sfaturilor dvs. 🙂
Răspuns
O altă abordare este utilizarea matricilor asociative awk, mai multe informații aici . Această linie produce ieșirea dorită:
awk -F "|" "{a[$1] += $3} END{print a["smiths"]}" filename.txt
Ca efect secundar, matricea stochează toate celelalte valori:
awk -F "|" "{a[$1] += $3} END{for (i in a) print i, a[i]}" filename.txt
Ieșire:
smiths 212 denniss 100 olivert 10
Comentarii
- Acesta este răspunsul corect
Răspuns
Foarte bine până acum. Tot ce trebuie să faceți este să adăugați un selector înainte de bloc pentru a adăuga suma. Aici verificăm dacă primul argument conține doar „smiths”:
awk "BEGIN {FS = "|"} ; $1 ~ /^smiths$/ {sum+=$3} END {print sum}"
Puteți scurta un pic specificând separatorul de câmp ca opțiune. În awk
este, în general, o idee bună să inițializați variabile pe linia de comandă:
awk -F"|" "$1 ~ /^smiths$/ {sum+=$3} END {print sum}"
Răspunde
Personal, aș prefera să păstrez secțiunea awk
cât mai simplă posibil și să faci cât de mult poți fără ea Logica combinată nu profită de puterea conductelor Unix și este astfel mai greu de înțeles, depanat sau modificat pentru cazuri de utilizare strâns legate.
cat filename.txt | perl -pe "s{.*|}{}g" | awk "{sum+=$1} END {print sum}"
Răspuns
cat filename.txt | grep smiths | awk -F "|" "{sum+=$NF} END {print sum}"
-
-F
opțiune pentru a specifica separatorul . -
$NF
este pentru „ultima coloană”.
Comentarii
-
cat
șigrep
nu sunt necesare aici. - De ce grep nu este necesar @Andrey? OP dorește să adauge numai " smiths " rânduri. ' ar trebui să modificați instrucțiunea awk, nu?
- @EL da, instrucțiunea awk ar trebui modificată în
/smiths/{...}
dacă apelul grep nu este acolo. Aceasta este o modificare banală, dar oferă beneficii semnificative: scade numărul de procese care rulează, simplifică controlul erorilor și clarifică codul.