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
jagrep
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.