Come eseguire il comando grep lines, in base a un determinato pattern?

8

Diciamo che ho un file che contiene 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 che contiene il pattern /aa/bbbb/cccccc , non ho bisogno della seconda riga che contiene caratteri extra, cioè ?dddddddd . Ora quando ho provato

grep '/aa/bbbb/cccccc' file

Quindi sono state selezionate entrambe le linee. Ho bisogno della linea completa in modo che grep -o non possa essere una soluzione.

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

    
posta heemayl 16.11.2014 - 12:55

3 risposte

7

Prova il comando grep di sotto che usa il parametro -P ( Perl-regexp ).

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

  • (?!\S) Il lookahead negativo asserisce che il carattere che segue la corrispondenza sarebbe qualsiasi carattere ma non un carattere non spaziale.

Un altro grep,

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

Attraverso python,

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='')

Salva il codice sopra in un file e chiamalo script.py . Quindi esegui lo script precedente con

python3 script.py /path/to/the/file/you/want/to/work/with
    
risposta data Avinash Raj 16.11.2014 - 12:58
10

Il modo più semplice sarebbe aggiungere uno spazio dopo il pattern:

$ 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 un lookahead positivo :

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

Oppure, con un lookahead 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 nient'altro che il tuo modello (senza spazi vuoti finali):

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

Oppure puoi semplicemente usare un piccolo script:

  • In awk:

    $ awk '=="/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 pattern

    $ 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
    
risposta data terdon 16.11.2014 - 13:50
2

Per integrare @AvinashRaj 's risposta , puoi usare anche questo comando.

grep -P '/a+/b+/c+(?!\S)' file
    
risposta data αғsнιη 16.11.2014 - 13:05

Leggi altre domande sui tag