Como posso fazer isso sem “awk” no shell script
Eu quero ler um arquivo de texto com algumas condições
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 123"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /favicon.ico HTTP/1.1" 404 - "
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 206"
111.196.10.3 - - [20/Jan/2020:19:43:50 +0200] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 377"
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /sit-3-shine.7.gif HTTP/1.1" 404 - "
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 375"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET /sit3-shine.7.gif HTTP/1.1" 200 15811"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 375"
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET /sit3-shine.7.gif HTTP/1.1" 200 15811"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 299"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /sit3-shine.7.gif HTTP/1.1" 200 15811"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 299"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET /sit3-shine.7.gif HTTP/1.1" 200 15811"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /favicon.ico HTTP/1.1" 404 -"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "HEAD / HTTP/1.1" 304 299"
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 302"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
1: Eu quero um script que conte os endereços IP no arquivo de texto e me forneça uma saída como esta
111.196.10.1 8
111.196.10.2 8
111.196.10.3 7
para o acima, eu escrevi um script
cat file | awk '{print $1}' | sort | uniq -c | sort -nr | awk '{print $2" "$1}'
está funcionando corretamente, mas eu quero isso sem "awk"
2: meu segundo requisito é, contar o endereço IP apenas quando o penúltimo número da linha começar com 2. a saída será
111.196.10.1 7
111.196.10.3 7
111.196.10.2 5
para isso, eu escrevi um script
grep '^[^"]*"[^"]*" 2' file | cut -d' ' -f1 | sort | uniq -c | sort -nr | awk '{print $2" "$1}'
também está funcionando corretamente, mas eu quero isso sem "awk"
Respostas
Você pode obter apenas a primeira coluna com Cut, então classificar os IPs resultantes e contá-los com Uniq.
cut -f1 -d' ' file | sort -n | uniq -cSe você só deseja contar na linha se o penúltimo número começar com a
2, basta adicionar um Grep.grep -E '2[0-9]* [0-9]+"$' t | cut -f1 -d' ' | sort -n | uniq -c
Testado na entrada de amostra.
Sem awk.
grep -oE '([0-9]+\.){3}[0-9]+' Input_file | sort | uniq -c
Com awk:
Você poderia tentar seguir, para fazer isso de uma vez awk.
awk '
match($1,/([0-9]+\.){3}[0-9]+/){ arr[substr($0,RSTART,RLENGTH)]++
}
END{
for(key in arr){
print key,arr[key]
}
}
' Input_file
OU se o primeiro campo for apenas o endereço IP, não precisamos mencionar substrno índice do array que poderíamos usar diretamente $1como segue.
awk '
match($1,/([0-9]+\.){3}[0-9]+/){
arr[$1]++
}
END{
for(key in arr){
print key,arr[key]
}
}
' Input_file
Explicação: Adicionando explicação detalhada acima.
awk ' ##Starting awk program from here.
match($1,/([0-9]+\.){3}[0-9]+/){ ##using match function to match IP address regex in current line.
arr[substr($0,RSTART,RLENGTH)]++ ##Create array arr which has index as sub string of matched regex from RSTART to RLENGTH.
}
END{ ##Starting END block of this program from here.
for(key in arr){ ##Traversing through arr from here.
print key,arr[key] ##printing key and array value here.
}
}
' Input_file ##Mentioning Input_file name here.
Você pode usar readpara ler dois campos da entrada e, em seguida, reproduzi-los em uma ordem diferente.
Então substitua
awk '{print $2" "$1}'
com
while read count ip; do
echo "$ip $count"
done