Mi tarea era imprimir la cantidad de archivos en el directorio actual sin usar los comandos ls
y wc
.
Había escrito las siguientes líneas en el script:
#!/bin/bash
find . -maxdepth 1 -type f \( ! -iname ".*" \) > list3
grep .* -c list3 > /dev/tty
La salida es:
..:0
.6.1c.sh.swp:1
list3:22
mientras que según tengo entendido solo debería ser:22
¿Por qué eso no funciona?
Respuesta1
¿Por qué grep
no funciona correctamente?
No funciona porque necesitas saber grep
cuál .*
es el patrón real que estás buscando.
grep '.*' -c list3
Si no usa comillas simples, su shell se expandirá .*
a los nombres de cada archivo en su directorio. Se llamaExpansión de nombre de archivo. Por ejemplo a.txt b.txt
, así grep
veremos:
grep a.txt b.txt -c list3
Desdecomillas simplesevitar que se produzca la expansión, este es el camino a seguir.
Donde tu grep
comando es incorrecto:
Por cierto, estás yendo en la dirección equivocada con el patrón aquí. El punto .
en una expresión regular coincidecualquiercarácter, y no el punto literal. Verla man
páginapara más información. Entonces su expresión regular actualmente dice: "busque cualquier carácter y luego una secuencia de cualquier carácter". Bastante redundante.
Si realmente quieres hacer coincidir:
[punto] [cualquier otra cosa]
… necesitas escapar del punto:
\.*
Donde find
se podría mejorar su comando:
No sé a qué te refieres con deshacerte de
\( ! -iname ".*" \)
Su find
comando antepondrá cualquier archivo con el punto para el directorio de trabajo actual, por lo que no eliminará nada aquí. Podrías simplemente haber ejecutado:
find . -maxdepth 1 -type f
Respuesta2
Para solucionar el problema original, contando archivos sin ls
y wc
:
Sintaxis de shell pura:
files=0
for i in *; do
[ -f "${i}" ] && files=$((files+1))
done
echo ${files}
Para agregar archivos ocultos al recuento, simplemente cambie la configuración global antes del for
ciclo.
Alternativamente: diversión con find
una expansión de shell:
echo $(($(find -maxdepth 1 -type f -printf '+1')))