Utilizzo di awk per sommare i valori di una colonna, in base ai valori di unaltra colonna

Sto cercando di sommare determinati numeri in una colonna utilizzando awk. Vorrei sommare solo la colonna 3 dei “fabbri” per ottenere un totale di 212. Posso sommare lintera colonna usando awk ma non solo i “fabbri”. Ho:

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

Inoltre sto usando lo stucco. Grazie per laiuto.

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

Rispondi

awk -F "|" "$1 ~ /smiths/ {sum += $3} END {print sum}" inputfilename 
  • Il flag -F imposta il separatore di campo; Lo metto tra virgolette singole perché è un carattere speciale della shell.
  • Quindi $1 ~ /smiths/ applica il seguente {blocco di codice} solo alle righe in cui il primo campo corrisponde alla regex /smiths/.
  • Il resto è lo stesso del tuo codice.

Tieni presente che poiché “non stai davvero usando unespressione regolare qui, solo un valore specifico, potresti altrettanto facilmente usa:

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

che controlla luguaglianza delle stringhe. Ciò equivale a usare la regex /^smiths$/, come menzionato in un altro risposta, che include lancora ^ per far corrispondere solo linizio della stringa (linizio del campo 1) e lancora $ solo a corrispondono alla fine della stringa. Non sono sicuro di quanto tu abbia familiarità con le espressioni regolari. Sono molto potenti, ma in questo caso potresti usare un controllo delluguaglianza delle stringhe altrettanto facilmente.

Commenti

  • A proposito, il mio riferimento awk preferito è grymoire.com/Unix/Awk.html . Pagina molto utile .
  • Grazie @ Wildcard! Sono stato in grado di aggregare ordinatamente una dimensione non compressa di file particolari in un grande archivio zip in base al tuo consiglio 🙂

Risposta

Un altro approccio è usare gli array associativi awk, maggiori informazioni qui . Questa riga produce loutput desiderato:

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

Come effetto collaterale, larray memorizza tutti gli altri valori:

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

Risultato:

smiths 212 denniss 100 olivert 10 

Commenti

  • Questa è la risposta giusta

Risposta

Finora molto buona. Tutto quello che devi fare è aggiungere un selettore prima del blocco per aggiungere la somma. Qui controlliamo che il primo argomento contenga solo “smiths”:

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

Puoi accorciarlo un po specificando il separatore di campo come opzione. In awk è generalmente una buona idea inizializzare le variabili sulla riga di comando:

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

Risposta

Personalmente preferirei mantenere la sezione awk il più semplice possibile e fare il più possibile senza di essa . La logica Comingled non sfrutta la potenza delle pipeline Unix ed è quindi più difficile da comprendere, eseguire il debug o modificare per casi duso strettamente correlati.

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

Risposta

cat filename.txt | grep smiths | awk -F "|" "{sum+=$NF} END {print sum}" 
  • -F opzione per specificare il separatore .
  • $NF è per “ultima colonna”.

Commenti

  • cat e grep non sono necessari qui.
  • Perché grep non è necessario @Andrey? OP desidera aggiungere solo " smiths " righe. ' avresti bisogno di modificare listruzione awk, giusto?
  • @EL sì, listruzione awk dovrebbe essere modificata in /smiths/{...} se la chiamata grep non è presente. Questa è una modifica banale, ma offre vantaggi significativi: riduce il numero di processi in esecuzione, semplifica il controllo degli errori e rende il codice più chiaro.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *