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}"
-
-Fvaihtoehto erottimen määrittämiseksi . -
$NFon tarkoitettu ”viimeiselle sarakkeelle”.
Kommentit
-
catjagrepovat 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.