Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

posted 2015-11-21 13:30:10 +0100

Důvod a vysvětlení chyby v Tvém řešení už zmínili ostatní, rád ukážů řešení mé:

awk '!/\[error\]/{a[$6]++}END{max=0;for(i in a){if(a[i]>max)max=a[i]} print max}' apache.log

Když jsem si zadání přečetl, hned mě napadlo awk. Jak je vidět, jde to hezky napsat pomocí jednoho awk, celkem jednoduše a snad i srozumitelně. A je to i dost rychlé (2n vs. 2n^2)

Pár lidí ale namítalo, že jsme awk ještě nebrali. Proto se báli i obyčejného

awk '{print $1}'

Které ušetřilo spoustu trápení a je mnohem mocnější než cut. Cut (bohužel) nezvládá více oddělovačů jdoucích po sobě.

Viz rozdíl

echo "  3" | cut -d\  -f1
echo "  3" | awk '{print $1}'

Na odstranění přebytečných mezer bez awk máme více možností. Výše zmíněný sed, nebo třeba grep -o

tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\ -f6 | sort | uniq -c | sort -nr | head -1 | grep -o '[0-9]*' | head -1

Někdo vtipně neodstraňoval mezery, ale pomocí echo je tam naopak přidával :-D Takže v řešení se fantazii meze nekladou.

Důvod a vysvětlení chyby v Tvém řešení už zmínili ostatní, rád ukážů řešení mé:

awk '!/\[error\]/{a[$6]++}END{max=0;for(i in a){if(a[i]>max)max=a[i]} print max}' apache.log

Když jsem si zadání přečetl, hned mě napadlo awk. Jak je vidět, jde to hezky napsat pomocí jednoho awk, celkem jednoduše a snad i srozumitelně. A je to i dost rychlé (2n rychlejší než 2x sort. Poprvé sort potřebuji, ale podruhé mi stačí jen najít maximální hodnotu (a kvůli tomu nepotřebuji vše řadit - O(n) vs. 2n^2)O(n log n))

Pár lidí ale namítalo, že jsme awk ještě nebrali. Proto se báli i obyčejného

awk '{print $1}'

Které ušetřilo spoustu trápení a je mnohem mocnější než cut. Cut (bohužel) nezvládá více oddělovačů jdoucích po sobě.

Viz rozdíl

echo "  3" | cut -d\  -f1
echo "  3" | awk '{print $1}'

Na odstranění přebytečných mezer bez awk máme více možností. Výše zmíněný sed, nebo třeba grep -o

tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\ -f6 | sort | uniq -c | sort -nr | head -1 | grep -o '[0-9]*' | head -1

Někdo vtipně neodstraňoval mezery, ale pomocí echo je tam naopak přidával :-D Takže v řešení se fantazii meze nekladou.

Důvod a vysvětlení chyby v Tvém řešení už zmínili ostatní, rád ukážů řešení mé:

awk '!/\[error\]/{a[$6]++}END{max=0;for(i in a){if(a[i]>max)max=a[i]} print max}' apache.log

Když jsem si zadání přečetl, hned mě napadlo awk. Jak je vidět, jde to hezky napsat pomocí jednoho awk, celkem jednoduše a snad i srozumitelně. A je to i rychlejší než 2x sort. Poprvé sort potřebuji, ale podruhé mi stačí jen najít maximální hodnotu (a kvůli tomu nepotřebuji vše řadit - O(n) vs. O(n log n))

Pár lidí ale namítalo, že jsme awk ještě nebrali. Proto se báli i obyčejného

awk '{print $1}'

Které ušetřilo spoustu trápení a je mnohem mocnější než cut. Cut (bohužel) nezvládá více oddělovačů jdoucích po sobě.

Viz rozdíl

echo "  3" | cut -d\  -f1
echo "  3" | awk '{print $1}'

Na odstranění přebytečných mezer bez awk máme více možností. Výše zmíněný sed, nebo třeba grep -o

tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\ -f6 | sort | uniq -c | sort -nr | head -1 | grep -o '[0-9]*' | head -1

Někdo vtipně neodstraňoval mezery, ale pomocí echo je tam naopak přidával :-D Takže v řešení se fantazii meze nekladou.

Ještě jeden na Babicu: Když nemáme sed, awk ani grep, tak tam dáme tr:

tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\  -f6 | sort | uniq -c | sort -nr | head -1 | tr -s ' ' | cut -d\  -f-2 | tr -d ' '

Důvod a vysvětlení chyby v Tvém řešení už zmínili ostatní, rád ukážů řešení mé:

awk '!/\[error\]/{a[$6]++}END{max=0;for(i in a){if(a[i]>max)max=a[i]} print max}' apache.log

Když jsem si zadání přečetl, hned mě napadlo awk. Jak je vidět, jde to hezky napsat pomocí jednoho awk, celkem jednoduše a snad i srozumitelně. A je to i rychlejší než 2x sort. Poprvé sort potřebuji, ale podruhé mi stačí jen najít maximální hodnotu (a kvůli tomu nepotřebuji vše řadit - O(n) vs. O(n log n))

Pár lidí ale namítalo, že jsme awk ještě nebrali. Proto se báli i obyčejného

awk '{print $1}'

Které ušetřilo spoustu trápení a je mnohem mocnější než cut. Cut (bohužel) nezvládá více oddělovačů jdoucích po sobě.

Viz rozdíl

echo "  3" | cut -d\  -f1
echo "  3" | awk '{print $1}'

Na odstranění přebytečných mezer bez awk máme více možností. Výše zmíněný sed, nebo třeba grep -o

tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\ -f6 | sort | uniq -c | sort -nr | head -1 | grep -o '[0-9]*' | head -1

Někdo vtipně neodstraňoval mezery, ale pomocí echo je tam naopak přidával :-D Takže v řešení se fantazii meze nekladou.

Ještě jeden na Babicu: Když nemáme sed, awk ani grep, tak tam dáme tr:tr: (POZOR, NEFUNGUJE!)

tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\  -f6 | sort | uniq -c | sort -nr | head -1 | tr -s ' ' | cut -d\  -f-2 | tr -d ' '

Důvod a vysvětlení chyby v Tvém řešení už zmínili ostatní, rád ukážů řešení mé:

awk '!/\[error\]/{a[$6]++}END{max=0;for(i in a){if(a[i]>max)max=a[i]} print max}' apache.log

Když jsem si zadání přečetl, hned mě napadlo awk. Jak je vidět, jde to hezky napsat pomocí jednoho awk, celkem jednoduše a snad i srozumitelně. A je to i rychlejší než 2x sort. Poprvé sort potřebuji, ale podruhé mi stačí jen najít maximální hodnotu (a kvůli tomu nepotřebuji vše řadit - O(n) vs. O(n log n))

Pár lidí ale namítalo, že jsme awk ještě nebrali. Proto se báli i obyčejného

awk '{print $1}'

Které ušetřilo spoustu trápení a je mnohem mocnější než cut. Cut (bohužel) nezvládá více oddělovačů jdoucích po sobě.

Viz rozdíl

echo "  3" | cut -d\  -f1
echo "  3" | awk '{print $1}'

Na odstranění přebytečných mezer bez awk máme více možností. Výše zmíněný sed, nebo třeba grep -o

tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\  -f6 | sort | uniq -c | sort -nr | head -1 | grep -o '[0-9]*' | head -1

Někdo vtipně neodstraňoval mezery, ale pomocí echo je tam naopak přidával :-D Takže v řešení se fantazii meze nekladou.

Ještě jeden na Babicu: Když nemáme sed, awk ani grep, tak tam dáme tr: (POZOR, NEFUNGUJE!)

tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\  -f6 | sort | uniq -c | sort -nr | head -1 | tr -s ' ' | cut -d\  -f-2 | tr -d ' '

Důvod a vysvětlení chyby v Tvém řešení už zmínili ostatní, rád ukážů řešení mé:

awk '!/\[error\]/{a[$6]++}END{max=0;for(i in a){if(a[i]>max)max=a[i]} print max}' apache.log

Když jsem si zadání přečetl, hned mě napadlo awk. Jak je vidět, jde to hezky napsat pomocí jednoho awk, celkem jednoduše a snad i srozumitelně. A je to i rychlejší než 2x sort. Poprvé sort potřebuji, ale podruhé mi stačí jen najít maximální hodnotu (a kvůli tomu nepotřebuji vše řadit - O(n) vs. O(n log n))

Pár lidí ale namítalo, že jsme awk ještě nebrali. Proto se báli i obyčejného

awk '{print $1}'

Které ušetřilo spoustu trápení a je mnohem mocnější než cut. Cut (bohužel) nezvládá více oddělovačů jdoucích po sobě.

Viz rozdíl

echo "  3" | cut -d\  -f1
echo "  3" | awk '{print $1}'

Na odstranění přebytečných mezer bez awk máme více možností. Výše zmíněný sed, nebo třeba grep -o

tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\   -f6 | sort | uniq -c | sort -nr | head -1 | grep -o '[0-9]*' | head -1

Někdo vtipně neodstraňoval mezery, ale pomocí echo je tam naopak přidával :-D Takže v řešení se fantazii meze nekladou.

Ještě jeden na Babicu: Když nemáme sed, awk ani grep, tak tam dáme tr: (POZOR, NEFUNGUJE!)

tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\  -f6 | sort | uniq -c | sort -nr | head -1 | tr -s ' ' | cut -d\  -f-2 | tr -d ' '

čas:

Fray

[email protected]:~$ wc -l <apache.log
 1000797
[email protected]:~$ du -sh apache.log
 140M   apache.log
[email protected]:~$ time awk '!/\[error\]/{a[$6]++}END{max=0;for(i in a){if(a[i]>max)max=a[i]} print max}' apache.log
375375

real    1m34.088s
user    1m33.637s
sys     0m0.405s
[email protected]:~$ time tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\  -f6 | sort | uniq -c | sort -nr | head -1 | ggrep -o '[0-9]*' | head -1
375375

real    1m15.272s
user    1m38.935s
sys     0m2.716s

Webdev

 [email protected] ~ $ ll apache.log
 -rw-r----- 1 bartimar users 145M Nov 21 20:52 apache.log
 [email protected] ~ $  time awk '!/\[error\]/{a[$6]++}END{max=0;for(i in a){if(a[i]>max)max=a[i]} print max}' apache.log
 375375

 real    0m4.094s
 user    0m1.820s
 sys     0m0.756s
 [email protected] ~ $  time tr -s ' ' <apache.log | grep -v '\[error\]' | cut -d\  -f6 | sort | uniq -c | sort -nr | head -1 | grep -o '[0-9]*' | head -1
 375375

 real    0m12.529s
 user    0m11.272s
 sys     0m7.916s