Quiero encontrar todos los archivos por la longitud de los nombres de los archivos.
Por ejemplo, si quiero buscar archivos de longitud 1, como a.go
, b.go
.
Pongo:
grep '.\{1\}' file
Pero esto no funciona. ¿Qué comando puedo usar para buscar archivos por longitud de nombre de archivo?
Respuesta1
Si solo desea encontrar los nombres de los archivos, puede usar el siguiente comando:
find -exec basename '{}' ';' | egrep '^.{100,}$'
Esto se ejecutará find
, extraerá el nombre del archivo o directorio basename
y luego buscará cualquier nombre de archivo o directorio que tenga al menos 100 caracteres. Si desea encontrar un nombre de archivo de una longitud exacta, utilice {100}
en lugar de {100,}
.
Si desea encontrar los nombres de archivos, incluida la ruta, haga esto:
find | egrep '/[^/]{100,}$'
Esto devolverá el nombre del archivo, incluida la ruta relativa al lugar donde ejecutó el comando de búsqueda.
Respuesta2
grep
busca patrones en el contenido de los archivos. Si quieres mirar elnombresde los archivos, puede usar un shell global (si desea considerar solo los nombres de archivos en el directorio actual):
echo ?.go
(Por cierto, es el shell el que evalúa el globo, no el echo
comando).
Si desea buscar directorios de forma recursiva, comenzando con el directorio actual, la herramienta a utilizar es find
:
find . -name '?.go'
(Tenga en cuenta que debe citar el patrón para evitar que el shell lo evalúe como un globo antes de find
invocarlo).
Respuesta3
En primer lugar, grep
busca a través delcontenidode archivos, no buscará nombres de archivos. Para eso quieres find
. No tiene una opción para establecer la longitud del nombre del archivo, pero puede analizar su salida para obtener lo que desea. Aquí hay algunos ejemplos que ejecuto en un directorio que contiene los siguientes archivos:
$ tree
.
├── a
├── ab
├── abc
├── abcd
└── dir
├── a
├── ab
├── abc
└── abcd
La búsqueda de archivos en este directorio devuelve:
$ find . -type f | sort
./a
./ab
./abc
./abcd
./dir/a
./dir/ab
./dir/abc
./dir/abcd
Entonces, para encontrar los archivos con una longitud de X, necesitaremos eliminar la ruta y hacer coincidir solo los caracteres después del último /
:
$ find . -type f | grep -P '/.{3}$'
El sed
comando simplemente elimina el archivo ./
. La -P
bandera activa las expresiones regulares compatibles con Perl que son necesarias para {n}
lo cual es una cosa PCRE y $
significa "coincidir con el final de la cadena".
También puedes simplemente hacer esto:
find . -type f | grep -P '/...$'
Eso está bien para números pequeños, escribir 15 puntos para hacer coincidir nombres de archivos de longitud 15 no es muy eficiente.
Finalmente, si desea ignorar la extensión y hacer coincidir solo el nombre del archivo, haga esto (como sugirió @slm):
find . -type f | grep -P '/.{1}\.'
Sin embargo, esto también encontrará archivos como a.bo.go
. Esto es mejor si sus nombres de archivos pueden contener más de uno .
:
find . -type f | grep -P '/.{1}\.[^.]+$'
NOTA: La solución anterior supone que tiene nombres de archivos relativamente sensatos que no contienen caracteres de nueva línea, etc. También contará y no ignorará los espacios en los nombres de archivos al calcular la longitud, que podría no ser la que desea. Si alguno de estos es un problema, hágamelo saber y actualizaré mi respuesta.
Respuesta4
No lo especifica, pero si los archivos están dentro de una estructura de directorio, puede usarlos find
para ubicar archivos de longitud 1, con la ayuda de grep
:
$ find . -type f | grep -P '/.{1}\.'
Ejemplo
$ find . -type f | grep -P '/.{1}\.' | head -10
./util-linux-2.19/include/c.h
./88366/a.bash
./89186/a.bash
./89563/b.txt
./89563/a.txt
./89563/c.txt
./89563/d.txt
./91734/2.c
./91734/4.c
./91734/1.c