Detección de patrón al final de una línea con grep


65

Si lo hago:

$ ls -R
.:
4Shared/  Cloud/

./4Shared:
UFAIZLV2R7.part3.rar

./Cloud:
UFAIZLV2R7.part2.rar.part
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part4.rar.part

Si solo quiero enumerar los .rararchivos, y uso grep , también me mostrará los .rar.partarchivos, lo que no es mi deseo.
Estoy resolviendo esto usando findo ls **/*.rarsegún lo dicho en este hilo y funcionan bien, pero me gustaría saber si es posible hacerlo a través de grep.

He intentado (pensando EOL):

ls -R | grep ".rar\n"

sin resultados
Creo que el problema radica en descubrir si la codificación se encuentra al final de la línea , pero no estoy seguro.

¿Alguna ayuda aquí, por favor?


¿Por qué querrías usar grepen este caso? ¿Por qué no find?
devnull

1
@devnull, saber cómo detectar patrones que solo están al final de una línea podría ser útil en muchos casos. Por ejemplo: portabilidad, uso en enrutadores con Linux demasiado simplista incorporado, uso con UnxUtils para Windows (su findcomando entra en conflicto con el de Windows) y ... aprendizaje ;-). La pregunta no es sobre "Listado de archivos en un directorio" (que es solo un ejemplo personalizado) sino más bien "Comprender el uso del comando grep"
Sopalajo de Arrierez

1
Honestamente, si estás contando con el final de una línea como tu separador, entonces deberías estar usando ls -1R.
mikeserv

1
Y ni siquiera lo necesitas grep. Mira mi respuesta.
mikeserv

@mikeserv, qué podría pasar sin el -1Rinterruptor. Al parecer, los resultados son los mismos.
Sopalajo de Arrierez

Respuestas:


89

El $ancla coincide con el final de una línea.

ls -R | grep '\.rar$'

También puedes usar findpara esto:

find . -name '*.rar'

No me di cuenta del "." necesita ser escapado en grep. ¿Se trata como un comodín?
thebunnyrules

1
@thebunnyrules "." en regex significa uno de cualquier carácter.
jordanm

10

Además de su pregunta, tenga en cuenta que .rarno solo coincide con ".rar" sino que coincide con todos los caracteres (incluidos .) antes del rar. En este caso, probablemente no sea un problema, pero .debe escaparse en expresiones regulares.

ls -R | grep "\.rar$"

¿Querías decir que .asces como un *ascpatrón? Entonces coincidirá, por ejemplo whereverasc,.
Sopalajo de Arrierez

2
@SopalajodeArrierez No, no coincide con cada grupo de caracteres, sino con cada uno de ellos, por ejemplo xrar.
Hauke ​​Laging

5

También puede indicar grepque busque su cadena comenzando en un límite de palabra. A .es uno de estos límites.

$ ls -R | grep '\brar$'

Ejemplo

Digamos que tengo estos datos de muestra.

$ ls -1
afile.rar
xrar
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part2.rar.part

Este comando solo encontraría el archivo con la .rarextensión.

$ ls -R | grep '\brar$'
afile.rar

¿Cómo funciona esto?

El metacarácter \bes un ancla como el símbolo de intercalación y el signo de dólar. Coincide en una posición que se llama "límite de palabra". Este partido es de longitud cero.

Situaciones donde esto no funcionará

Si tiene archivos con nombres, blah-rarestos también se detectarán.

$ ls -R | grep '\brar$'
afile-rar
afile.rar

Esto se debe a que los caracteres que no sean alfanuméricos generalmente se consideran caracteres de límite, por lo que pasarían por alto este enfoque.


Parece ser lo mismo a primera vista, pero es ligeramente diferente, de hecho. Gracias @slm. ¿Le molesta si uso comillas dobles en "lugar de comillas simples?
Sopalajo de Arrierez

1
@SopalajodeArrierez: no, funciona de cualquier manera. Esto encontrará cualquier archivo que se pueda nombrar comenzando con / .rar. Pero estos no serán un problema con el uso de ls -R. Solo si por casualidad lo usaste ls -Ra.
slm

¿Alguno de ustedes estaría interesado en explicar esta ligera diferencia al público?
Hauke ​​Laging

@HaukeLaging El -Pcambio a grepen mi ejemplo. Eso desencadena la interpretación PCRE del argumento.
slm

1
@SopalajodeArrierez: si un archivo contiene un carácter de nueva línea ( \n) que es un carácter legal. Sin ls -1Rembargo, forzará la visualización de los archivos en una sola columna.
slm

0

Solo haz :

ls -1R -I"?" -I"??" -I"???" -I"*[!.][!r][!a][!r]"

No necesitas grepnada.

NOTA: Lo anterior funciona ... excepto que todavía se pone al menos afile-rar y no entiendo por qué. Lo dejaré aquí, pero no estoy orgulloso de ello. En cualquier caso, como otros han dicho:

find . '*.rar'

Esto no bloqueó los archivos nombrados xraro afile-rar.
slm

Todavía obtengo los otros archivos en la salida.
slm

@slm ¿Qué otros archivos? Creo que podría ser porque son demasiado cortos. Acabo de notar eso yo mismo. Yo también lo arreglé.
mikeserv

Los archivos afile-rary xrartodavía se están incluyendo en la salida. No hay cambio con tus últimas modificaciones tampoco. Problema molesto no? Es divertido tratar de resolverlo sin los métodos habituales 8-)
slm

@slm Sí, es por eso que vengo aquí. No entiendo por qué -dashpasa. La xrarcosa que podía manejar, pero no el -dash.que no entienden el-dash.
mikeserv

0

Use comillas simples para hacer que $ funcione como fin de línea. Si desea grep con alguna variable también, use la combinación de comillas dobles y simples como se muestra a continuación:

grep "$var"'$'

Mi publicación anterior fue eliminada diciendo que está duplicada. Déjame explicarte cómo esto es diferente.

Las otras publicaciones mencionan el uso completo de comillas dobles ""o el uso completo de comillas simples ''. Ambos tienen sus propias limitaciones. Lo siguiente lo explica.

El problema con todas las comillas dobles es el siguiente: grep "pattern$"da el siguiente error:Illegal variable name.

Y el uso de todas las comillas simples funciona, pero si desea la sustitución de variables, todas las comillas simples no funcionarán. Por ejemplo:

Si tengo una cadena A_BOOK, incluidas otras cadenas en un archivo ARCHIVO.

$ cat FILE
A_BOOK
B_BOOK_NOT_LAST
C_BOOK

Si configuro el LIBRO a una variable BK

set BK = BOOK

Si utilizo todas las comillas dobles, aparece el siguiente error: grep "${BK}$" FILE*1er $ para la sustitución de variables, 2do para el final del patrón ( nombre de variable ilegal ).

Si hago grep con todas las comillas simples, la sustitución de variables no ocurre. grep '${BK}$' FILEno devuelve nada

Si uso una combinación de comillas dobles y simples, obtengo lo que espero. Comillas dobles para la sustitución de variables y comillas simples para el final del patrón.

$ grep "${BK}"'$'  # << gives expected output
A_BOOK
C_BOOK

Parece que estás usando csh. La "foo$"sintaxis funciona bien en sh y family.
Olorin

Si Olorin Estoy usando tcsh. Gracias por señalar eso.
user274900

0

Si después de seguir lo anterior y nada funciona, podría deberse a finales de línea. Para arreglar, haz: dos2unix pr0n.txty haz tu grepotra vez.

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.