Comment puis-je faire cela sans «awk» dans le script shell
Je veux lire un fichier texte avec certaines conditions
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: Je veux un script qui compte les adresses IP dans le fichier texte et me donne une sortie comme celle-ci
111.196.10.1 8
111.196.10.2 8
111.196.10.3 7
pour ce qui précède, j'ai écrit un script
cat file | awk '{print $1}' | sort | uniq -c | sort -nr | awk '{print $2" "$1}'
ça marche correctement mais je veux ça sans "awk"
2: ma deuxième exigence est de ne compter l'adresse IP que lorsque l'avant-dernier numéro de la ligne commence par 2. la sortie sera
111.196.10.1 7
111.196.10.3 7
111.196.10.2 5
pour cela, j'ai écrit un script
grep '^[^"]*"[^"]*" 2' file | cut -d' ' -f1 | sort | uniq -c | sort -nr | awk '{print $2" "$1}'
ça marche aussi correctement mais je veux ça sans "awk"
Réponses
Vous ne pouvez obtenir que la première colonne avec Cut, puis trier les adresses IP résultantes et les compter avec Uniq.
cut -f1 -d' ' file | sort -n | uniq -cSi vous ne voulez compter dans la ligne que si l'avant-dernier nombre commence par a
2, ajoutez simplement un Grep.grep -E '2[0-9]* [0-9]+"$' t | cut -f1 -d' ' | sort -n | uniq -c
Testé sur l'entrée d'échantillon.
Sans awk.
grep -oE '([0-9]+\.){3}[0-9]+' Input_file | sort | uniq -c
Avec awk:
Pourriez-vous s'il vous plaît essayer de suivre, pour le faire en un seul 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 si le 1er champ n'est que l'adresse IP, nous n'avons pas besoin de mentionner substrdans l'index du tableau que nous pourrions utiliser directement $1comme suit.
awk '
match($1,/([0-9]+\.){3}[0-9]+/){
arr[$1]++
}
END{
for(key in arr){
print key,arr[key]
}
}
' Input_file
Explication: Ajout d'une explication détaillée ci-dessus.
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.
Vous pouvez utiliser readpour lire deux champs à partir de l'entrée, puis les faire écho dans un ordre différent.
Alors remplacez
awk '{print $2" "$1}'
avec
while read count ip; do
echo "$ip $count"
done