2016-04-25 16 views
0

Hallo allerseits: Jetzt habe ich ein Tomcat-Zugriffsprotokoll mit 3G-Bytes namens urls, jede Zeile ist eine URL. Ich möchte jede URL zählen und diese URLs nach der Anzahl der URLs sortieren. Ich habe es so gemacht:Wie wird eine 3G-Byte-Zugriffsprotokolldatei sortiert?

awk '{print $0}' urls | sort | uniq -c | sort -nr >> output 

Aber es dauerte wirklich lange Zeit, um diesen Job zu beenden, es dauerte schon 30 Minuten und es funktioniert immer noch. Protokolldatei ist wie unten:

/open_api/borrow_business/get_apply_by_user 
/open_api/borrow_business/get_apply_by_user 
/open_api/borrow_business/get_apply_by_user 
/open_api/borrow_business/get_apply_by_user 
/loan/recent_apply_info?passportId=Y20151206000011745 
/loan/recent_apply_info?passportId=Y20160331000000423 
/open_api/borrow_business/get_apply_by_user 
... 

Gibt es eine andere Art und Weise, die ich verarbeiten konnte und sortieren ein 3G-Bytes-Datei? Danke im Voraus!

+0

Wenn alles, was Sie eine Zählung jeder URL ist wollen, dann stehen die Chancen, dass man das Ganze ein Befehl tun können. Bearbeiten Sie Ihre Frage, um uns ein Beispiel Ihrer Protokolldatei und die gewünschte Ausgabe zu zeigen. –

+1

Falls es wirklich der 'sort' Befehl selbst ist, der das Ganze verlangsamt, können Sie die' --parallel = N' Option versuchen – fab

+0

Es wäre mir viel besser für Sie, das gleiche wie Klartext einzuschließen, anstatt ein Bildschirmfoto. Könntest du das machen? –

Antwort

0

Ich bin mir nicht sicher, warum Sie awk im Moment verwenden - es tut nichts nützliches.

Ich würde vorschlagen, so etwas wie dies mit:

awk '{ ++urls[$0] } END { for (i in urls) print urls[i], i }' urls | sort -nr 

Diese eine Zählung jeder URL aufbaut und sortiert dann die Ausgabe.

+0

Ich denke, der Grund, warum es so langsam ist, ist die Datei zu groß. Es ist immer noch langsam von dir. – leo

+1

@leo der Schlüssel ist, wenn Toms Lösung schneller ist als deine. Deine Datei wurde 4 Mal durchgespielt und sollte langsamer als Toms sein. Wie definieren Sie "langsam" "schnell" bei dieser Aufgabe? Was ist dein Maßstab? – Kent

+0

@leo Dies reduziert die Größe der Liste, die Sie sortieren möchten, auf die Anzahl der verschiedenen URLs, sodass eine bessere Chance besteht, dass sie in den Speicher passt. Sie versuchen, eine relativ große Datei zu verarbeiten, sodass Sie nicht erwarten können, dass sie sofort erscheint! –

0

erzeugt I eine Beispieldatei von 3.200.000 Zeilen, zu 3 GB Höhe mit Perl wie folgt aus:

perl -e 'for($i=0;$i<3200000;$i++){printf "%d, %s\n",int rand 1000, "0"x1000}' > BigBoy 

I dann versucht, es in einem Schritt das Sortieren, gefolgt von einem in 2 Hälften aufgeteilt und die Hälften getrennt Sortier und Mischen der Ergebnisse, dann Aufteilen in 4 Teile und getrenntes Sortieren und Zusammenführen, dann Aufteilen in 8 Teile und getrenntes Sortieren und Zusammenführen.

Dies führte, auf meiner Maschine zumindest in einer sehr signifikanten Beschleunigung.

enter image description here

Hier ist das Skript. Der Dateiname ist fest codiert als BigBoy, könnte aber leicht geändert werden und die Anzahl der Teile, in die die Datei aufgeteilt werden soll, muss als Parameter angegeben werden.

#!/bin/bash -xv 
################################################################################ 
# Sort large file by parts and merge result 
# 
# Generate sample large (3GB with 3,200,000 lines) file with: 
# perl -e 'for($i=0;$i<3200000;$i++){printf "%d, %s\n",int rand 1000, "0"x1000}' > BigBoy 
################################################################################ 
file=BigBoy 
N=${1:-1} 
echo $N 
if [ $N -eq 1 ]; then 
    # Straightforward sort 
    sort -n "$file" > sorted.$N 
else 
    rm sortedparts-* parts-* 2> /dev/null 
    tlines=$(wc -l < "$file") 
    echo $tlines 
    ((plines=tlines/N)) 
    echo $plines 
    split -l $plines "$file" parts- 
    for f in parts-*; do 
     sort -n "$f" > "sortedparts-$f" & 
    done 
    wait 
    sort -n -m sortedparts-* > sorted.$N 
fi 

Unnötig zu sagen, die resultierenden sortierten Dateien identisch sind :-)

+1

Ich neige dazu, mit 'i = $ ((i + 1))' zu gehen, da ich gelernt habe, dass [++ 'nicht von POSIX benötigt wird] (http://pubs.opengroup.org/onlinepubs/009695399/utilities /xcu_chap02.html).Vielleicht verpasse ich hier etwas, aber ist die Größe der endgültigen "Sortierung" nicht die gleiche? –

+1

Oh, ich war mir nicht bewusst, dass das Inkrement nicht in POSIX ist, es funktioniert auf meinem Mac und ich neige dazu, es zu benutzen. Ich werde aktualisieren. Die Zusammenführungssortierung sollte immer nur eine Zeile von jeder Eingabedatei lesen (da alle bereits sortiert sind) und nur eine Zeile im Speicher für jede Eingabe halten, dann die erste in der Reihenfolge ausgeben und dann die verbrauchte Zeile durch eine andere ersetzen lesen. Ich dachte mir, dass die Sorte den meisten RAM verwendet - ich könnte falsch liegen - aber es ist vielleicht einen Versuch wert. –

+0

Basierend auf [die Antworten auf diese Frage] (http://unix.stackexchange.com/q/279096/67817), scheint es, dass "sort" wahrscheinlich etwas Ähnliches wie Ihr Ansatz unter der Haube tun wird. Dachte, du könntest interessiert sein :) –

Verwandte Themen