Jag försöker summera vissa nummer i en kolumn med awk
. Jag vill summera bara kolumn 3 i ”smederna” för att få totalt 212. Jag kan summera hela kolumnen med awk
men inte bara ”smederna”. Jag har:
awk "BEGIN {FS = "|"} ; {sum+=$3} END {print sum}" filename.txt
Jag använder också kitt. Tack för all hjälp.
smiths|Login|2 olivert|Login|10 denniss|Payroll|100 smiths|Time|200 smiths|Logout|10
Svar
awk -F "|" "$1 ~ /smiths/ {sum += $3} END {print sum}" inputfilename
-
-F
-flaggan ställer in fältseparatorn; Jag lägger det i enstaka citat eftersom det är en speciell skalkaraktär. - Sedan tillämpar
$1 ~ /smiths/
följande {kodblock} endast på rader där det första fältet matchar regex/smiths/
. - Resten är densamma som din kod.
Observera att eftersom du inte verkligen använder en regex här, bara ett specifikt värde, kan du lika gärna användning:
awk -F "|" "$1 == "smiths" {sum += $3} END {print sum}" inputfilename
Vilket kontrollerar stränglikhet. Detta motsvarar att använda regex /^smiths$/
, som nämnts i en annan svar, som inkluderar ^
ankare för att endast matcha början på strängen (början av fält 1) och $
ankare till endast matcha slutet av strängen. Inte säker på hur bekant du är med regexes. De är väldigt kraftfulla, men i det här fallet kan du använda en strängjämnhetskontroll lika lätt.
Kommentarer
- Förresten är min favorit-awk-referens grymoire.com/Unix/Awk.html . Mycket hjälpsam sida .
- Tack @Wildcard! Jag kunde prydligt samla en okomprimerad storlek på vissa filer i stort zip-arkiv baserat på ditt råd 🙂
Svar
Ett annat tillvägagångssätt är att använda awk associativa arrayer, mer info här . Denna rad ger önskad utgång:
awk -F "|" "{a[$1] += $3} END{print a["smiths"]}" filename.txt
Som en bieffekt lagrar arrayen alla andra värden:
awk -F "|" "{a[$1] += $3} END{for (i in a) print i, a[i]}" filename.txt
Output:
smiths 212 denniss 100 olivert 10
Kommentarer
- Detta är rätt svar
Svar
Mycket bra hittills. Allt du behöver göra är att lägga till en väljare före blocket för att lägga till summan. Här kontrollerar vi att det första argumentet endast innehåller ”smiths”:
awk "BEGIN {FS = "|"} ; $1 ~ /^smiths$/ {sum+=$3} END {print sum}"
Du kan förkorta det lite genom att ange fältseparatorn som ett alternativ. I awk
är det i allmänhet en bra idé att initialisera variabler på kommandoraden:
awk -F"|" "$1 ~ /^smiths$/ {sum+=$3} END {print sum}"
Svar
Jag personligen föredrar att hålla avsnittet awk
så enkelt som möjligt och göra så mycket du kan utan det Comedled-logik utnyttjar inte kraften i Unix-rörledningar och är därför svårare att förstå, felsöka eller modifiera för närbesläktade användningsfall.
Svar
cat filename.txt | grep smiths | awk -F "|" "{sum+=$NF} END {print sum}"
-
-F
alternativ för att ange separator . -
$NF
är för ”sista kolumnen”.
Kommentarer
-
cat
ochgrep
är onödiga här. - Varför är grep onödigt @Andrey? OP vill bara lägga till " smiths " rader. Du ' du behöver ändra awk-uttalandet, eller hur?
- @EL ja, awk-uttalandet bör ändras till
/smiths/{...}
om grep-samtalet inte finns där. Detta är en triviell modifiering, men det ger betydande fördelar: minskar antalet pågående processer, förenklar felkontrollen och gör koden tydligare.