Käyttämällä awk: tä sarakkeen arvojen yhteenlaskemiseen toisen sarakkeen arvojen perusteella

Yritän laskea yhteen tiettyjä sarakkeen lukuja käyttämällä saraketta awk. Haluaisin tiivistää vain ”seppien” sarakkeen 3, jotta saat yhteensä 212. Voin tiivistää koko sarakkeen käyttämällä awk, mutta ei vain ”sepät”. Minulla on:

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

Käytän myös kittiä. Kiitos avusta.

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

Vastaa

awk -F "|" "$1 ~ /smiths/ {sum += $3} END {print sum}" inputfilename 
  • -F -lippu asettaa kentän erottimen; Laitoin sen lainausmerkkeihin, koska se on erityinen kuorimerkki.
  • Sitten $1 ~ /smiths/ käyttää seuraavaa {koodilohkoa} vain riveihin, joiden ensimmäinen kenttä vastaa regex-koodia /smiths/.
  • Loppuosa on sama kuin koodisi.

Huomaa, että koska et oikeastaan käytä täällä regexiä, vain tiettyä arvoa, voit yhtä helposti käyttö:

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

Mikä tarkistaa merkkijonon tasa-arvon. Tämä vastaa regex /^smiths$/ -asetuksen käyttöä, kuten toisessa mainitaan vastaus, joka sisältää ^ -ankkurin vastaamaan vain merkkijonon alkua (kentän 1 alku) ja $ -ankkuria vain vastaa merkkijonon loppua. Etkö ole varma, kuinka tuttuja olet regexeistä. Ne ovat erittäin tehokkaita, mutta tässä tapauksessa voit käyttää merkkijonojen tasaustarkistusta yhtä helposti.

Kommentit

  • Muuten suosikkini awk-viite on grymoire.com/Unix/Awk.html . Erittäin hyödyllinen sivu .
  • Kiitos @ Wildcard! Pystyin yhdistämään tietyn tiedoston pakkaamattoman koon suuressa zip-arkistossa neuvojesi perusteella 🙂

vastaus

Toinen tapa on käyttää awk-assosiatiivisia taulukoita, lisätietoja täällä . Tämä rivi tuottaa halutun tuloksen:

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

Sivuvaikutuksena taulukko tallentaa kaikki muut arvot:

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

Tulos:

smiths 212 denniss 100 olivert 10 

Kommentit

  • Tämä on oikea vastaus

Vastaus

Erittäin hyvä tähän mennessä. Sinun tarvitsee vain lisätä valitsin ennen lohkoa lisätäksesi summan. Täällä tarkistamme, että ensimmäinen argumentti sisältää vain ”sepät”:

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

Voit lyhentää tätä hieman määrittelemällä kentän erottimen vaihtoehdoksi. Kohdassa awk on yleensä hyvä aloittaa muuttujat komentorivillä:

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

Vastaa

Haluan henkilökohtaisesti pitää awk -osion mahdollisimman yksinkertaisena ja tehdä niin paljon kuin voit ilman sitä Yhdistetty logiikka ei hyödynnä Unix-putkistojen voimaa, ja sitä on siis vaikeampaa ymmärtää, virheenkorjaus tai muokata läheisesti liittyvissä käyttötapauksissa.

Vastaa

cat filename.txt | grep smiths | awk -F "|" "{sum+=$NF} END {print sum}" 
  • -F vaihtoehto erottimen määrittämiseksi .
  • $NF on tarkoitettu ”viimeiselle sarakkeelle”.

Kommentit

  • cat ja grep ovat tässä tarpeettomia.
  • Miksi grepiä ei tarvita @Andrey? OP haluaa lisätä vain " sepät " rivejä. Sinun ' joudut muuttamaan awk-käskyä, eikö?
  • @EL kyllä, awk-käsky tulisi muuttaa muotoon /smiths/{...} jos grep-kutsu ei ole siellä. Tämä on vähäpätöinen muunnos, mutta se tarjoaa merkittäviä etuja: vähentää käynnissä olevien prosessien määrää, yksinkertaistaa virheenhallintaa ja tekee koodista selkeämmän.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *