¿Cómo grep líneas, basadas en un cierto patrón?


8

Digamos que tengo un archivo que contiene las siguientes dos líneas:

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

Necesito obtener la línea que contiene el patrón /aa/bbbb/ccccccsolamente, no necesito la segunda línea que contiene caracteres adicionales, es decir ?dddddddd. Ahora cuando lo intenté

grep '/aa/bbbb/cccccc' file

Luego se seleccionan las dos líneas. Necesito la línea completa, así grep -oque no podría ser una solución.

¿Cuál podría ser la posible solución usando grep para que solo se seleccione la primera línea en función del patrón de búsqueda?

Respuestas:


7

Pruebe el siguiente comando grep que utiliza el parámetro -P( Perl-regexp ).

grep -P '(?<!\S)/aa/bbbb/cccccc(?!\S)' file
  • (?<!\S)Esta mirada hacia atrás negativa afirma que el carácter que precede a la cadena /aa/bbbb/ccccccsería cualquier carácter que no sea espacio.

  • (?!\S) La búsqueda anticipada negativa afirma que el personaje que sigue a la coincidencia sería cualquier personaje que no sea espacio.

Otro grep,

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

A través de pitón,

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

Guarde el código anterior en un archivo y asígnele el nombre script.py. Luego ejecute el script anterior por

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

Gracias hombre. Por cierto, ¿se puede hacer esto utilizando expresiones regulares / extendidas en lugar de expresiones regulares perl?
heemayl

1
como terdon publicado, podrías simplementegrep '/aa/bbbb/cccccc ' file
Avinash Raj

Pero lo anterior no imprimirá las líneas que solo tienen /aa/bbbb/cccccccadena.
Avinash Raj

También puedes combinar eso congrep -E '/aa/bbbb/cccccc(\s+|$)' file
terdon

sí, asígrep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file
Avinash Raj

10

La forma más sencilla sería agregar un espacio después de su patrón:

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

O, para que coincida con todo tipo de espacios en blanco:

$ 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

O, con una anticipación positiva :

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

O, con una anticipación negativa :

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

O puedes revertir el partido:

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

O, para coincidir también con las líneas que contienen nada más que su patrón (sin espacios en blanco al final):

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

O bien, puede usar un pequeño script:

  • En awk:

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

    O, si no sabe en qué campo está su patrón

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

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

@terdon grep -v 'c?' filepor qué no lo usas grep -v '?' fileporque el archivo solo tiene dos líneas.
αғsнιη

@KasiyA cierto, solo quería mantener un poco el patrón. Sin embargo, tienes toda la razón, en este caso particular, grep -v '?'sería suficiente.
terdon

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.