grep * .c no funciona

0

Tengo una lista de ".c" (archivos c) en el directorio actual.

Tengo que encontrar todos los archivos .c en el directorio actual.

El comando que se puede utilizar id ls * .c

Pero, otra forma es usar grep.

entonces si doy

 ls | grep *.c

No devuelve ningún resultado para este comando, mientras que para otros tipos de archivos como ".java", ".txt" da los resultados esperados.

¿Hay algún significado especial para "* .c" en el comando grep? ¿O puedo saber la razón de este comportamiento?

vivek_nk
fuente
2
Por que no solo ls *.c?
Johnsyweb
@Johnsyweb, probablemente tenga curiosidad por saber por qué no funcionó. No sobre el resultado.
KurzedMetal
@KurzedMetal: Claro, pero tengo curiosidad por saber cómo llegó allí (o ella).
Johnsyweb
1
probablemente tengas más de 1 archivo: por ejemplo, archivo1.c archivo2.c archivo3.c archivo4.c. El shell expande esto a: ls | grep file1.c file2.c file3.c file4.c: esto significa "ls | cmd". aquí cmd es "grep file1.c in_the_other_files_listed", que no devuelve nada ya que ninguno de los otros archivos contiene la cadena "file1.c" (ls | greo esto: ignorará la salida de ls y grep "this" en el archivo "that" )
Olivier Dulac

Respuestas:

7

*.c es un patrón glob, mientras que grep busca expresiones regulares.

Usted quiere ls | grep '\.c$' Si quieres encontrar todos los archivos que terminan en .c.

grep coincide con cualquier subcadena de forma predeterminada, no con toda la cadena, por lo que no necesita escribir algo que coincida con el principio del nombre de archivo. Si quisieras escribir eso, sería .* en una expresión regular. . indica "cualquier carácter excepto una línea que termina", y * indica "cualquier número (cero o más) de la expresión anterior".

Porque . tiene un significado especial en una expresión regular, si desea hacer coincidir un literal ., necesitas escapar con \. Porque \ tiene un significado especial en el shell, necesita citar la expresión regular con comillas simples ( ' ).

Para asegurarse de que coincida solo al final del nombre de archivo, use $, que coincide con el final de la línea.

Brian Campbell
fuente
3

O use buscar, luego obtenga una lista si es necesario, por ejemplo.

find . -name "*.c" -exec ls -al {} \;

Encontrar es muy útil.


fuente
2
Esto irá a los subdirectorios también por cierto.
texasbruce
1
si desea evitar que entre en subdirectorios, cámbielo a find . -maxdepth 1 -name "*.c" -exec ls -al {} \;
nullrevolution
0

grep está buscando el contenido de los archivos para su REGEX, no los nombres de los archivos.

Dave Sexton
fuente
Este tipo no merecía ser bajado de votos, es lo que el comando ls | grep *.c se está realizando si hay más de un archivo en el directorio actual, debido a la expansión de bash, como expliqué en mi respuesta.
KurzedMetal
0

Por favor, inténtalo:

ls | grep '\.c$'

El RegExp "*" no es necesario

Langusten Gustel
fuente
0

grep "* .c" buscará LITERALMENTE la cadena "* .c", es decir, la cadena "asterisco punto c" sin expandirla para que signifique "todos los archivos con extensión .c", por lo que no está encontrando Cualquier cosa en la salida de "ls":

# touch b.c

# ls -1 | grep "* .c"

el resultado está vacío.

Si desea expansión, debe usar egrep (grep extendido) que hace expresiones regulares. Pero aquí son un poco diferentes:

# ls -1 | egrep ".*.c"
b.c

es decir, la expresión regular es:. *. c (cualquier carácter que no sea de nueva línea se multiplica por cero o más veces, cualquier carácter que no sea de nueva línea [se podría escapar para que signifique literalmente "punto"], "c")

mrkafk
fuente
0

Es necesario citar asteriscos:

ls | grep "*.c"

o el shell bash lo va a expandir y ejecutar algo como:

ls | grep 1.c 2.c 3.c

(Suponiendo que tenga archivos nombrados 1.c, 2.c, 3.c en el directorio actual).

Lo cual no va a dar el resultado que estás esperando.

Lo que realmente hará es buscar el contenido de 2.c y 3.c y mostrar las líneas que tiene la cadena 1.c en él, que probablemente no sean ninguno, y es por eso que obtienes un resultado vacío.

(Solo estoy explicando por qué obtuviste una salida vacía, como dijo otro, *.c no es un regex válido tampoco)

KurzedMetal
fuente