Je souhaite obtenir les requêtes "GET" à partir des journaux de mon serveur.
Par exemple, ceci est le journal du serveur
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] code 404, message File not fo$
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] "GET /hello HTTP/1.1" 404 -
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] code 404, message File not fo$
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] "GET /ss HTTP/1.1" 404 -
Quand j'essaye avec grep ou awk,
Adi:~ adi$ awk '/GET/, /HTTP/' serverlogs.txt
il donne
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:32:27] "GET /hello HTTP/1.1" 404 -
1.0.0.127.in-addr.arpa - - [10/Jun/2012 15:41:57] "GET /ss HTTP/1.1" 404 -
Je veux juste afficher: bonjour et ss
Y a-t-il un moyen de faire cela?
En supposant que vous avez gnu grep, vous pouvez utiliser une expression rationnelle de style Perl pour effectuer une recherche positive:
grep -oP '(?<=GET\s/)\w+' file
Si vous n'avez pas gnu grep, je vous conseillerais simplement d'utiliser sed:
sed -n '/^.*GET[[:space:]]\{1,\}\/\([-_[:alnum:]]\{1,\}\).*$/s//\1/p' file
Si vous vous en apercevez, cela peut être grandement simplifié:
sed -n '/^.*GET\s\+\/\(\w\+\).*$/s//\1/p' file
En fin de compte, vous n’avez certainement pas besoin de tuyaux pour accomplir cela. grep
ou sed
seul suffira.
Dans ce cas, étant donné que le fichier journal a une structure connue, une option consiste à utiliser cut
pour extraire la 7ème colonne (les champs sont désignés par défaut par des onglets).
grep GET log.txt | cut -f 7
utilisez un tuyau si vous utilisez grep:
grep -o /he.* log.txt | grep -o [^/].*
grep -o /ss log.txt | grep -o [^/].*
[^ /] signifie extraire les lettres après le symbole ^ de la sortie de grep
J'essayais de le faire et suis tombé sur ce lien: https://www.unix.com/Shell-programming-and-scripting/153101-print-next-Word-after-found-pattern.html
Résumé: Utilise grep pour trouver les lignes correspondantes, puis utilise awk pour trouver le motif et imprimer le champ suivant:
grep pattern logfile | \
awk '{for(i=1; i<=NF; i++) if($i~/pattern/) print $(i+1)}'
Si vous voulez connaître les occurrences uniques:
grep pattern logfile | \
awk '{for(i=1; i<=NF; i++) if($i~/pattern/) print $(i+1)}' | \
sort | \
uniq -c
Il est souvent plus facile d'utiliser un pipeline plutôt qu'une seule expression régulière complexe. Cela fonctionne sur les données que vous avez fournies:
fgrep GET /tmp/foo |
egrep -o 'GET (.*) HTTP' |
sed -r 's/^GET \/(.+) HTTP/\1/'
Ce pipeline renvoie les résultats suivants:
hello
ss
Il y a certainement d'autres moyens de faire le travail, mais cela fonctionne manifestement sur le corpus fourni.
gawk '{match($7,/\/(\w+)/,a);} length(a[1]){print a[1]}' log.txt
hello
ss
Si vous avez gawk
, la commande ci-dessus utilisera la fonction match
pour sélectionner la valeur souhaitée à l'aide de l'expression rationnelle et la stocker dans un tableau a
.