cryptosteve
Anmeldungsdatum: 17. April 2007
Beiträge: 815
Wohnort: Nähe Hamburg
|
Moin,
ich möchte aus einer simplen Textliste eine TOP5-Liste (nach Anzahl der Vorkommnisse) greppen, kriegs aber nicht so recht gebacken. Eine Listenzeile ist immer wie folgt aufgebaut: Zeit Host Datei, z.B. 1208101519 localhost index.html. Das Logfile sieht beispielhaft wie folgt aus: 1208101519 localhost index.html
1208101519 localhost index.html
1208101519 host1 index.php
1208101519 host2 index1.html
1208101519 host1 index2.html
1208101519 host5 index1.html
1208101519 host4 index.php
1208101519 host3 index1.html
1208101519 host3 index1.html
1208101519 host5 index2.html
1208101519 host5 index2.html
1208101519 host4 index3.html
1208101519 host1 index4.html Ich möchte jetzt jeweils die ersten fünf (oder hier hilfsweise drei) häufigsten Vorkommen der Spalte 'host' und 'datei' haben. Jemand eine Idee dazu? Edit: Code-Block korrigiert
|
uname
Anmeldungsdatum: 28. März 2007
Beiträge: 6030
Wohnort: 127.0.0.1
|
Das suche ich auch noch, vor allem addiert über viele Zeilen. Ich löse das z.B. per Perl. Meistens gebe ich jedoch vorher auch die Anzahl aus.
script.pl
#! /usr/bin/perl
$feld = $ARGV[0];
while (<STDIN>)
{
$ent = $_;
@werte = split (" ", $ent);
$eintrag = $werte[$feld];
$sum{$eintrag}++;
}
foreach $ent (keys %sum)
{
$zahl = sprintf "%06d", $sum{$ent} ;
print $zahl . ";" . $ent . "\n";
} cat datei.txt | ./script.pl 1 | sort -r
Ausgabe:
000003;host5
000003;host1
000002;localhost
000002;host4
000002;host3
000001;host2 Alternativ kann man natürlich das "sprintf" weglassen und mit "sort -gr" sortieren, erhöht jedoch bei vielen Einträgen nicht gerade die Übersicht.
|
cryptosteve
(Themenstarter)
Anmeldungsdatum: 17. April 2007
Beiträge: 815
Wohnort: Nähe Hamburg
|
Hi,
vielen Dank zunächst für Deine Antwort. Es freut mich schonmal, dass es offenbar nicht mal eben so ein trivialer Einzeiler ist, auf den ich bloss nicht gekommen bin. ☺
Dein Skript schaue ich mir gerne mal an, vielleicht kann ich das für meine Zwecke adaptieren. Die Anzahl vorne einstellig und dann mit Doppelpunkt, dann ist's ja schon gut brauchbar. Vielleicht fällt ja trotzdem noch jemandem eine egrep- oder sonstwie geartete Lösung ein?!
|
uname
Anmeldungsdatum: 28. März 2007
Beiträge: 6030
Wohnort: 127.0.0.1
|
Das Problem ist, dass es über mehrere Zeilen geht. Im Prinzip muss man Werte in Variablen schreiben und die Variablen entsprechen irgendwelchen Bezeichnungen, also Hash-Variablen wie $sum{host1}. Mag sein, dass man das mit "awk" irgendwie bauen kann. Das Semikolon ist im übrigen recht praktisch für CSV-Dateien und die Weiterbearbeitung in OO Calc bzw. MS Excel. Normalerweise ist die Auswertung dann auch mehrdimensional und nicht ganz so trivial. Die Eingabe über Pipes ist im übrigen recht praktisch um mehrere dieser Mini-Perl-Scripte zu kombinieren.
|
cryptosteve
(Themenstarter)
Anmeldungsdatum: 17. April 2007
Beiträge: 815
Wohnort: Nähe Hamburg
|
Jip, ungefähr bei dem Gedanken bin ich dann auch gescheitert. Einzelne Sachen rauszugreppen ist kein Thema, aber das dann auch noch zu zählen (nicht nur für einen Wert, sonder für alle vorkommenden) hat mich dann doch überfordert.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17621
Wohnort: Berlin
|
echo "1208101519 localhost index.html
1208101519 localhost index.html
1208101519 host1 index.php
1208101519 host2 index1.html
1208101519 host1 index2.html
1208101519 host5 index1.html
1208101519 host4 index.php
1208101519 host3 index1.html
1208101519 host3 index1.html
1208101519 host5 index2.html
1208101519 host5 index2.html
1208101519 host4 index3.html
1208101519 host1 index4.html" | sed 's/[^ ]* //' | sort | count.sh | sort -nr | head -n 5
2: localhost index.html
2: host5 index2.html
2: host3 index1.html
1: host5 index1.html
1: host4 index.php
falls Du nach den Top 5 - Kombinationen suchst, und nicht nach den Top 5 jeweils. count.sh: wasmacht.sh count.sh
/home/stefan/bin/count.sh: ASCII text
echo "/**
count.sh
get Input like
aaa
aab
aab
aac
aac
bxy
and output
aaa 1
aab 2
aac 2
bxy 1
Assuming (not testing) input is sorted.
@author Stefan Wagner (c) GPLv3
@date Do Mar 18 03:01:49 CEST 2010
*/" > /dev/null
function count ()
{
count=0
while read line
do
if [[ $line."foo" = $oldline."foo" ]]
then
count=$((count+1))
else
if [[ oldline."foo" != ."foo" ]]
then
echo -e $count ":\t" $oldline
fi
count=1
oldline=$line
fi
done
echo -e $count ":\t" $oldline
}
function usage ()
{
echo -e "Usage:\tcat file | sort | count.sh"
echo -e "\t\tcounts identic lines."
echo -e "\t\tassumes lines are sorted ascending, like from 'sort file | count.sh'"
}
if (( $# != 0))
then
usage
exit 1
fi
count
|
uname
Anmeldungsdatum: 28. März 2007
Beiträge: 6030
Wohnort: 127.0.0.1
|
War doch trivial. Uniq kann auch zählen, war mir entfallen: cat datei.txt | cut -d" " -f2 |sort |uniq -c | sort -gr
|
cryptosteve
(Themenstarter)
Anmeldungsdatum: 17. April 2007
Beiträge: 815
Wohnort: Nähe Hamburg
|
user unknown schrieb:
falls Du nach den Top 5 - Kombinationen suchst, und nicht nach den Top 5 jeweils.
Nein, ich suche einzeln. Es wäre aber kein Problem, das Skript einfach zweimal durchlaufen zu lassen, z.B. einmal mit Parameter "2" (für Spalte zwei), einmal mit "3" (für Spalte 3). Dazu noch 'ne Idee?
|
uname
Anmeldungsdatum: 28. März 2007
Beiträge: 6030
Wohnort: 127.0.0.1
|
Hier nun die Top5 beim Feld 2: cat datei.txt | cut -d" " -f2 |sort |uniq -c | sort -gr | head -n 5
|
cryptosteve
(Themenstarter)
Anmeldungsdatum: 17. April 2007
Beiträge: 815
Wohnort: Nähe Hamburg
|
Mhhmm ... das ist ja schonmal sehr schick. Klappt hier im Kurztest, morgen teste ich es am tatsächlichen Logfile.
|
Antiqua
Anmeldungsdatum: 30. Dezember 2008
Beiträge: 4534
|
sort +2 datei.txt | uniq -c | sort -gr sortiert datei.txt nach +0 = erstes Feld +1 = zweites Feld +2 = drittes Feld
|
cryptosteve
(Themenstarter)
Anmeldungsdatum: 17. April 2007
Beiträge: 815
Wohnort: Nähe Hamburg
|
OMG ... es ist doch ein simpler Einzeiler ☹ Trotzdem danke ... 👍
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17621
Wohnort: Berlin
|
Ist dieses -c - Flag bei uniq relativ neu, oder habe ich es nur bisher übersehen? Mir kommt es so vor, als habe ich es vor paar Monaten schonmal gesehen, aber wieder verdrängt, weil es mein schönes count-Programm überflüssig macht. ☺
|
Antiqua
Anmeldungsdatum: 30. Dezember 2008
Beiträge: 4534
|
uniq --version
uniq (GNU coreutils) 6.12
Copyright © 2008 Free Software Foundation, Inc.
hats jedenfalls schon...
|
Antiqua
Anmeldungsdatum: 30. Dezember 2008
Beiträge: 4534
|
noch eine Möglichkeit, diesmal mit awk: textfile:
1208101519 localhost index.html
1208101519 localhost index.html
1208101519 host1 index.php
1208101519 host2 index1.html
1208101519 host1 index2.html
1208101519 host5 index1.html
1208101519 host4 index.php
1208101519 host3 index5.html
1208101519 host3 index5.html
1208101519 host5 index5.html
1208101519 host5 index5.html
1208101519 host4 index5.html
1208101519 host1 index5.html
1208101519 host3 index5.html
1208101519 host5 index5.html
1208101519 host5 index5.html
1208101519 host4 index5.html
1208101519 host1 index5.html
1208101519 host3 index5.html
1208101519 host5 index2.html
1208101519 host5 index2.html
1208101519 host4 index3.html
1208101519 host1 index4.html
1208101519 host3 index1.html
1208101519 host5 index2.html
1208101519 host5 index2.html
1208101519 host4 index3.html
1208101519 host1 index4.html
1208101519 host3 index1.html
1208101519 host5 index2.html
1208101519 host5 index2.html
1208101519 host4 index3.html
1208101519 host1 index4.html
1208101519 host3 index1.html
1208101519 host5 index2.html
1208101519 host5 index2.html
1208101519 host4 index3.html
1208101519 host1 index4.html nach den hosts sortiert:
ich@slacker:~/ubuntu/sorttest$ awk '{ print $2 }' textfile | sort | uniq -c | sort -gr
13 host5
8 host1
7 host4
7 host3
2 localhost
1 host2
1
nach den Seiten sortiert:
ich@slacker:~/ubuntu/sorttest$ awk '{ print $3 }' textfile | sort | uniq -c | sort -gr
12 index5.html
9 index2.html
5 index1.html
4 index4.html
4 index3.html
2 index.php
2 index.html
1
|