Comportamiento extraño de "ls -a | grep ^ \. "


10

Quería enumerar el contenido de un pwd y mostrar solo el archivo que comienza con punto. Lo intenté ls -a | grep ^\.pero no puedo entender por qué la salida contiene también los archivos que no comienzan con punto. Por ejemplo:

Pictures
.pip
.pki
.profile
projects
Public

Sé que puedo lograr lo que quiero. ls -ld .*Tengo curiosidad por este comportamiento de grep que no puedo explicar.



¿Por qué no simplemente ls -d .*enumerar todos los archivos que comienzan con .?
Barmar

Una nota de advertencia: nunca canalice la salida de ls a otro comando. Use find en su lugar. Tiene demasiadas ideosincrasias para confiar. Ver: Pitfall 1 en mywiki.wooledge.org/BashPitfalls - ¡fue el # 1! El resto del sitio también es genial.
Joe

Respuestas:


20

Cite el argumento para grep, asíls -a | grep '^\.'

La razón de esto es que el shell lo maneja \.y lo vuelve a convertir en simple ., que grepluego se trata como un comodín de un solo carácter. En caso de duda, siempre cite una cadena que contenga (o pueda contener) un carácter especial para el shell.


¿Por qué Shell ignora \?
ps-aux

\ es una secuencia de escape que hace que el shell trate el siguiente carácter como literal. En esto grep ^\\., \\ es tratado por el shell como una barra diagonal inversa simple y nuevamente el grep trata la barra diagonal inversa simple seguida por el punto como punto literal.
Avinash Raj

11

Debe poner la expresión regular grep entre comillas.

ls -a | grep '^\.'

Nota: No analice la salida del lscomando .


¿Por qué es malo analizar la salida de ls?
ps-aux

Desde el enlace: en su modo predeterminado, si la salida estándar no es una terminal, ls separa los nombres de archivo con nuevas líneas. Esto está bien hasta que tenga un archivo con una nueva línea en su nombre.
Michael Durrant

@Michael Durrant: Sugeriría que permitir nuevas líneas en los nombres de archivos es un error importante del sistema.
jamesqf

@jamesqf: vea las nuevas líneas en los nombres de archivo (especialmente la respuesta de sml ).
don_crissti

0

Si ejecuta cmd ls -a | grep ^ \. entonces grep no considere "\" como un carácter especial y significado de "." No te escapes.

Cuando usamos cmd ls -a | grep "^ \." entonces grep considera "\" como un carácter especial y significado de "." se escapa Le dará un resultado como se esperaba.

Si desea utilizar grep cmd sin comillas, también debe escapar del carácter "\". Puede haber esperado el resultado sin comillas dobles siguiendo el comando. ls -a | grep ^ \\.

Para obtener detalles sobre el significado de caracteres especiales en Regex, consulte el siguiente enlace. http://www.regular-expressions.info/quickstart.html

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.