efficiënt sorteren | uniq voor het geval van een groot aantal duplicaten

Summary : is there a way to get the unique lines from a file and the number of occurrences more efficiently than using a sort | uniq -c | sort -n?

Details: I often pipe to sort | uniq -c | sort -n when doing log analysis to get a general trending of which log entries show up the most/least etc. This works most of the time - except when I'm dealing with a very large log file that ends up with a very large number of duplicates (in which case sort | uniq -c ends up taking a long time).

Example: The specific case I'm facing right now is for getting a trend from an 'un-parametrized' MySQL bin log to find out which queries are run the most. For a file of a million entries which I pass through a grep/sed combination to remove parameters - resulting in about 150 unique lines - I spend about 3 seconds grepping & sedding, and about 15s sorting/uniq'ing.

Currently, I've settled with a simple C++ program that maintains a map of < line, count > - which does the job in less than a second - but I was wondering if an existing utility already exists.

3
GNU sort zal gebruik tijdelijke bestanden om gegevens te bevatten die te groot zijn om in één keer in het geheugen te passen.
toegevoegd de auteur ephemient, de bron
Wacht tot je C ++ -programma geen geheugen meer heeft :-D
toegevoegd de auteur user405725, de bron
Waarom zou het gebruik van een kaart om de telling van occurrences op te slaan meer geheugen gebruiken dan elke occurrence (dat wil zeggen de eerste sort in de sortering | uniq -c | sort -n) te sorteren?
toegevoegd de auteur Ali-Akber Saifee, de bron
@ephemient: bedankt, dat wees me in de richting van het controleren van de versie van coreutils.
toegevoegd de auteur Ali-Akber Saifee, de bron
dit is de cpp-implementatie voor verwijzing link
toegevoegd de auteur Ali-Akber Saifee, de bron

1 antwoord

Ik weet niet zeker wat het verschil in prestaties zal zijn, maar u kunt de sortering | vervangen uniq -c met een eenvoudig script awk . Omdat je veel duplicaten en hashes hebt in plaats van te sorteren, zou ik me kunnen voorstellen dat het sneller is:

 awk '{c[$0]++}END{for(l in c){print c[l], l}}' input.txt | sort -n
5
toegevoegd
Als je een grote map met bestanden hebt die je met dit script wilt sorteren en uniq, kun je het gewoon zo uitvoeren: awk '{c [$ 0] ++} END {for (l in c) {print c [l], l}} '<(zoek. -type f | xargs cat) | sorteer -n
toegevoegd de auteur omribahumi, de bron
Enorme verbetering bij het zoeken naar unieke gebruikersagenten in een Apache-logboek.
toegevoegd de auteur Andras Gyomrey, de bron
bedankt, dit werkt best goed voor bestanden met een groot aantal dupes. Bleek echter dat de twee systemen waarop ik aan het testen was (Mac OSX Lion en RHEL 4) een waanzinnig oude versie van sort (5.x) hadden die de prestaties met coreutils 8.x vergelijkt (getest op ubuntu 12.04) er is geen probleem, de soort, uniq, sorteerketen werkt als een charme.
toegevoegd de auteur Ali-Akber Saifee, de bron
vergelijking tussen coreutils 5.x en 8.x voor geïnteresseerden: link
toegevoegd de auteur Ali-Akber Saifee, de bron