Come grep linee, basato su un certo modello?


8

Diciamo che ho un file contenente le seguenti due righe:

2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
2014-05-05      09:12:17    /aa/bbbb/cccccc?dddddddd    16767 

Ho bisogno di ottenere la riga contenente /aa/bbbb/ccccccsolo il modello , non ho bisogno della seconda riga contenente caratteri extra, ad es ?dddddddd. Adesso quando ci ho provato

grep '/aa/bbbb/cccccc' file

Quindi entrambe le linee selezionate. Ho bisogno della linea completa, quindi grep -onon potrebbe essere una soluzione.

Quale potrebbe essere la possibile soluzione usando grep in modo che solo la prima riga venga selezionata in base al modello di ricerca?

Risposte:


7

Prova il seguente comando grep che utilizza il parametro -P( Perl-regexp ).

grep -P '(?<!\S)/aa/bbbb/cccccc(?!\S)' file
  • (?<!\S)Questo aspetto negativo afferma che il carattere che precede la stringa /aa/bbbb/ccccccsarebbe qualsiasi ma non un carattere non spaziale.

  • (?!\S) Il lookahead negativo afferma che il personaggio che segue la partita sarebbe qualsiasi ma non un personaggio non spaziale.

Un altro grep,

 grep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file

Attraverso il pitone,

script.py

#!/usr/bin/python3
import re
import sys
file = sys.argv[1]
with open(file, 'r') as f:
    for line in f:
        for i in line.split():
            if i == "/aa/bbbb/cccccc":
                print(line, end='')

Salvare il codice sopra in un file e denominarlo come script.py. Quindi eseguire lo script sopra

python3 script.py /path/to/the/file/you/want/to/work/with

Grazie uomo. A proposito, questo può essere fatto usando regex normale / esteso piuttosto che perl regex?
Hememl

1
come ha pubblicato Terdon, potresti semplicementegrep '/aa/bbbb/cccccc ' file
Avinash Raj,

Ma quanto sopra non stampa le righe che hanno solo una /aa/bbbb/ccccccstringa.
Avinash Raj,

Puoi eguagliarlo anche congrep -E '/aa/bbbb/cccccc(\s+|$)' file
terdon,

sì, in questo modogrep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file
Avinash Raj,

10

Il modo più semplice sarebbe quello di aggiungere uno spazio dopo il modello:

$ grep '/aa/bbbb/cccccc ' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Oppure, per abbinare tutti i tipi di spazi bianchi:

$ grep  '/aa/bbbb/cccccc[[:space:]]' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

O

$ grep -P '/aa/bbbb/cccccc\s+' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Oppure, con uno sguardo positivo :

$ grep -P '/aa/bbbb/cccccc(?=\s)' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Oppure, con uno sguardo negativo :

$ grep -P '/aa/bbbb/cccccc(?!\S)' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Oppure puoi invertire la partita:

$ grep  -v 'c?' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Oppure, per abbinare anche le linee che non contengono altro che il tuo pattern (nessuno spazio vuoto finale):

grep -P '/aa/bbbb/cccccc(\s+|$)' file 
grep -E '/aa/bbbb/cccccc(\s+|$)' file 

Oppure puoi semplicemente usare un piccolo script:

  • In awk:

    $ awk '$3=="/aa/bbbb/cccccc"' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    

    Oppure, se non sai in quale campo si trova il tuo schema

    $ awk '{for(i=1;i<=NF;i++){if($i=="/aa/bbbb/cccccc"){print}}}' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    
  • In Perl

    $ perl -ane 'print if grep {$_ eq "/aa/bbbb/cccccc"} @F' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    

@terdon nel grep -v 'c?' fileperché non lo usi grep -v '?' fileperché il file ha solo due righe.
αғsнιη,

@KasiyUn vero, volevo solo mantenere un po 'il modello. Hai ragione, però, in questo caso particolare, grep -v '?'basterebbe.
terdon,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.