2011-08-04 8 views
7
2011-07-01 ... /home/todd/logs/server_log_1.log ... 
2011-07-02 ... /home/todd/logs/server_log_2.log ... 
2011-07-03 ... /home/todd/logs/server_log_3.log ... 

J'ai un fichier ressemble à ce qui précède. Je veux extraire les noms de fichiers à partir de lui et la sortie à STDOUT comme:sed/awk: Motif extrait du flux de texte

server_log_1.log 
server_log_2.log 
server_log_3.log 

Quelqu'un pourrait-il aider? Merci!

Le modèle de nom de fichier est server_log_xxx.log et il ne se produit qu'une seule fois sur une ligne.

+0

Comme les noms de fichiers peuvent contenir à peu près tout caractère (espaces, sauts de ligne, les caractères de contrôle, sur la plupart des systèmes de fichiers unix, quoi que ce soit, sauf ' « \ 0'' et ' »/' '), ces 3 lignes pourraient être un nom de fichier valide. Il n'y a aucun moyen de reconnaître les noms de fichiers de manière fiable, sauf si vous ajoutez des restrictions sur les noms de fichiers valides et les choses qui peuvent apparaître dans les deux '...'. Vous voulez particulièrement faire attention car les fichiers journaux qui enregistrent des variables non contrôlées par l'utilisateur (par exemple, les entrées, les noms d'hôtes) peuvent être des cibles pour des attaques par injection contre des parseurs mal écrits. – jw013

+0

jw013: non, vous avez besoin de '' \ n'' dans le nom de fichier, sinon ces 3 lignes sont trois entrées –

+0

@yi ''\ n'' est un caractère valide dans les noms de fichiers. Vous ne pouvez pas vraiment faire de correspondance sur "tous les noms de fichiers possibles", et à titre d'exemple, j'ai souligné que la ligne entière ou toute concaténation de lignes (jusqu'à la limite de longueur du nom de fichier) est un nom de fichier valide. Maintenant que Todd a spécifié le motif qu'il cherche, le problème devient plus raisonnable (bien que la partie 'xx' ne soit pas encore spécifiée, ils sont probablement destinés à représenter des chiffres). Je ne suis pas vraiment ce que vous dites "non". – jw013

Répondre

16

En supposant l'espace réservé « xxx » est seulement chiffres:

grep -o 'server_log_[0-9]\+\.log' 
+0

Bonne réponse, merci! – Dagang

0
sed 's|.*/\([^/ ]*\).*|\1|' infile 
+3

Ajoutez 'p' à la fin de la commande' s' et ajoutez l'option '-n' sauf si vous voulez voir chaque ligne qui ne correspond pas au modèle. – jw013

0

Avec awk et votre modèle d'entrée:

awk 'BEGIN {FS="/"} 
    { print gensub(" .*$","","g",$5) }' INPUTFILE 

Voir ce l'action ici: https://ideone.com/kcadh

HTH

3

pipe votre fichier via la commande suivante:

sed 's/.*\(server_log_[0-9]\+\.log\).*/\1/' 
+0

sed 's /.* \ (server_log_ [0-9] \ + \. Log \). */\ 1 /' est plus simple, non? – Dagang

+0

À droite, mais avec des accolades échappées. Cela n'a pas fonctionné pour moi avant parce que j'ai omis '. *' '. Mise à jour de ma solution –