¿Qué expresiones coincidirían con el patrón (^[0-9]..[a-zA-Z ]+$) en el comando grep? fiesta de linux

¿Qué expresiones coincidirían con el patrón (^[0-9]..[a-zA-Z ]+$) en el comando grep? fiesta de linux

Estoy tratando de entender qué expresiones (^[0-9]..[a-zA-Z ]+$)detecta exactamente la expresión regular en grepel comando (terminal de Linux)

Lo sé si escribiera el siguiente comando:

grep ^[0-9]..[a-zA-Z] filename.txt

Detectaré cualquier línea que contenga expresiones como 92afg Pero no estoy seguro de cuál +$significa ni qué tipo de expresiones podré detectar con el comando

grep ^[0-9]..[a-zA-Z]+$ filename.txt

Intenté abrir un nuevo archivo de texto y simplemente escribir expresiones que pensé que se detectarían, pero ninguna coincidía, así que agradecería una explicación para esto.

Respuesta1

Analicémoslo. En primer lugar, tenga en cuenta que esta RegExp utiliza el"Expresión regular extendida"sintaxis (ERE): +es un metacarácter que no funciona en la sintaxis de "expresión regular básica" que grepse usa de forma predeterminada (lo que significa que coincidiría consigo mismo y requeriría un literal +en esa posición), por lo que si desea usar esa expresión regular con grep, deberá pasar la -Eopción.

  • Es ^un ancla que une esta posición de la expresión regular al inicio de la línea.
  • Es [0-9]una lista de caracteres y coincidirá con cualquier (1) carácter que se encuentre en el rango de clasificación entre 0y 9. Lo que eso comprende exactamente depende del "orden de clasificación", determinado entre otros por la variable de entorno LC_COLLATE.
  • Coincide .con cualquier carácter, por lo que dos ..significa "dos caracteres cualesquiera".
  • La [a-zA-Z]parte posterior es una lista de caracteres y coincidirá con los caracteres (1) que se encuentran entre ay zy, además, con los que se encuentran entre Ay Z. Nuevamente, ¡lo que eso significa depende del orden de clasificación!
  • El +significa "uno o más de los anteriores"
  • Es $un ancla que une esta posición de la expresión regular al final de la línea.

Entonces, tu RegExse pretende(1) haga coincidir cualquier línea que

  • empezar con cualquier dígito
  • seguido de dos caracteres cualesquiera
  • y solo contiene letras (pero al menos una) hasta el final de la línea.

(1) para conocer lo que realmente podría hacer, consulte a continuación

Algunas notas

  1. En su ejemplo, utiliza la expresión regular sin comillas. Eso significa que todos los caracteres están abiertos a la interpretación del shell antes de pasarlos al grepcomando. Si su patrón contiene $caracteres globales ( *¡ ?y [...]listas de caracteres!), el shell puede intentar realizar una expansión variable (reemplazando así partes de su RegEx) o expandir patrones globales en posiblemente varios nombres de archivos, de modo que al final tenga más argumentos. en la línea de comando que originalmente pretendías. Otros caracteres que son especiales del shell ( >, #y ;similares) pueden provocar comportamientos aún más inesperados. Deberías usar

    grep -E '^[0-9]..[a-zA-Z]+$' filename.txt
    

    en cambio. Tenga en cuenta que puede deshacerse de los anclajes de apertura y cierre utilizando la -xbandera para imponer la coincidencia de "línea completa":

    grep -x -E '[0-9]..[a-zA-Z]+' filename.txt
    
  2. Las listas de caracteres que contienen rangos (como a-z) sonpeligrosoporque es posible que no te den lo que piensas. Ingenuamente se podría esperar que coincidan con todos los caracteres que se encuentran entre el carácter inicial y final de la tabla ASCII, pero eso sólo es cierto para la Cconfiguración regional. En otras configuraciones regionales (y en particular en las configuraciones regionales del sistema generalmente configuradas, como en_US.UTF-8), el orden de clasificación es algo así aAbB ... zZcomo que a-ztambién coincidiría con la mayoría de las letras mayúsculas. Además, la coincidencia en realidad no se realiza en el nivel de caracteres individuales sino en "elementos de intercalación", lo que significa en algunas regiones, inclusocombinaciones de varias letraspuede coincidir (por ejemplo, dzsen húngaro)! Veresta respuesta(o, en general, la mayoría de las respuestas de @Stéphane Chazelas sobre la coincidencia de patrones) para obtener más información. Si desea asegurarse de que sus rangos funcionen, establezca el orden de clasificación al menos para el comando dado a través de

    LC_COLLATE="C" grep -E ' ... ' filename.txt
    

Respuesta2

+significa "una o más repeticiones del anterior", $es "fin de línea". Tenga en cuenta la diferencia versus *con significa "cero o más repeticiones".

Básicamente significa: cualquier línea que comience con un dígito, seguida de dos caracteres de cualquier tipo y posteriormente una o más letras (posiblemente mayúsculas)¹ hasta el final de la línea.

(¹ tenga cuidado, es posible que algunas configuraciones regionales no solo tengan las 26 letras que esperaría en AZ o az, por ejemplo, èo ŷsegún el idioma)

Para obtener una buena guía sobre expresiones regulares, recomiendo encarecidamenteEl hermoso sitio web de Grimorio., que también recomiendo de todo corazón, por ejemplo, sedy awk.


¿Por qué no coincide?

+es parte de las expresiones regulares extendidas (y de lo contrario se interpreta como un +signo literal).

Entonces, para usarlo +como "una o más repeticiones", use el -Eindicador -y greptambién componga la expresión regular para evitar problemas con los caracteres especiales del shell:

grep -E '^[0-9]..[a-zA-Z]+$' filename.txt

información relacionada