awk
Handige one-liners - gemiddelde berekenen van een CSV enz
Zoeken…
Robuuste verwerking van tabelgegevens (CSV et al.)
Het verwerken van tabelgegevens met awk is heel eenvoudig, op voorwaarde dat de invoer correct is opgemaakt. De meeste software die tabelgegevens produceert, gebruikt specifieke functies van deze reeks indelingen, en awk- programma's die tabelgegevens verwerken, zijn vaak specifiek voor gegevens die door een specifieke software zijn geproduceerd. Als een meer generieke of robuuste oplossing vereist is, bieden de populairste talen bibliotheken met veel functies in tabelgegevens:
- optionele kolomnamen op de eerste regel
- mengsel van geciteerde en niet-geciteerde kolomwaarden
- verschillende scheidingstekens
- gelokaliseerde formaten voor zwevende nummers
Hoewel het zeker mogelijk is om al deze functies netjes en generiek met awk te gebruiken, is dit waarschijnlijk niet de moeite waard.
Twee kolommen in tabelgegevens uitwisselen
Een bestand gegeven met ; als een kolomscheidingsteken. Het permuteren van de eerste en de tweede kolom wordt bereikt door
awk -F';' -v 'OFS=;' '{ swap = $2; $2 = $1; $1 = swap; print }'
Bereken het gemiddelde van waarden in een kolom uit tabelgegevens
Een bestand gegeven met ; als een kolomscheidingsteken. We berekenen het gemiddelde van de waarden in de tweede kolom met het volgende programma, de verstrekte invoer is de lijst met cijfers van een studentengroep:
awk -F';' '{ sum += $2 } END { print(sum / NR) }' <<EOF
Alice;2
Victor;1
Barbara;1
Casper;4
Deborah;0
Ernest;1
Fabiola;4
Giuseppe;4
EOF
De output van dit programma is 2.125 .
Onthoud dat NR het nummer bevat van de regel die wordt verwerkt, in het END blok bevat het daarom het totale aantal regels in het bestand.
Vergeet niet dat in veel toepassingen (monitoring, statistieken) de mediaan veel nuttiger informatie is. Zie het bijbehorende voorbeeld.
Specifieke kolommen in tabelgegevens selecteren
We gaan uit van een bestand met; als een kolomscheidingsteken. Het selecteren van een specifieke set kolommen vereist alleen een afdrukinstructie . Het volgende programma selecteert bijvoorbeeld de kolommen 3, 4 en 7 uit de invoer:
awk -F';' -v 'OFS=;' '{ print $3, $4, $7 }'
Het is zoals gebruikelijk mogelijk om zorgvuldiger lijnen te kiezen om af te drukken. Het volgende programma selecteert de kolommen 3, 4 en 7 uit de invoer wanneer het eerste veld Alice of Bob :
awk -F';' -v 'OFS=;' '($1 == "Alice") || ($1 == "Bob") { print $3, $4, $7 }'
Bereken de mediaan van waarden in een kolom uit tabelgegevens
Een bestand gegeven met ; als een kolomscheidingsteken. We berekenen de mediaan van de waarden in de tweede kolom met het volgende programma, geschreven voor GNU awk . De verstrekte invoer is de cijferlijst van een studentengroep:
gawk -F';' '{ sample[NR] = $2 }
END {
asort(sample);
if(NR % 2 == 1) {
print(sample[int(NR/2) + 1])
} else {
print(sample[NR/2])
}
}' <<EOF
Alice;2
Victor;1
Barbara;1
Casper;4
Deborah;0
Ernest;1
Fabiola;4
Giuseppe;4
EOF
De output van dit programma is 1 .
Onthoud dat NR het nummer bevat van de regel die wordt verwerkt, in het END blok bevat het daarom het totale aantal regels in het bestand.
Veel implementaties van awk hebben geen functie om arrays te sorteren, die daarom moeten worden gedefinieerd voordat de bovenstaande code kan worden gebruikt.
Een reeks lijnen tussen twee patronen selecteren
Patroonafstemming kan effectief worden gebruikt met awk omdat het de acties die erop volgen, dwz { pattern } { action } , bestuurt. Een cool gebruik van het matchen van patronen is om meerdere tussen twee patronen in een bestand te selecteren, bijvoorbeeld patternA en patternB
$ awk '/patternA/,/patternB/' file
Neem aan dat mijn bestandsinhoud als volgt is en dat ik alleen de lijnen tussen het bovenstaande patroon wil extraheren: -
$ cat file
This is line - 1
This is line - 2
patternA
This is line - 3
This is line - 4
This is line - 5
patternB
This is line - 6
$ awk '/patternA/,/patternB/' file
patternA
This is line - 3
This is line - 4
This is line - 5
patternB
De bovenstaande opdracht doet geen specifieke { action } behalve het afdrukken van de overeenkomende lijnen, maar specifieke acties binnen de subset van lijnen kunnen worden toegepast met een actieblok ( {} ).