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.

ps-aux
fuente
¿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.

roaima
fuente
¿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 .

Avinash Raj
fuente
¿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

AVJ
fuente