¿Cómo enumerar solo archivos y no directorios de un directorio Bash?

84

¿Cómo puedo enumerar todos los archivos de una carpeta pero no sus carpetas o subarchivos? En otras palabras: ¿Cómo puedo enumerar solo los archivos?

Rodrigo
fuente

Respuestas:

113

Usando find:

find . -maxdepth 1 -type f

El uso de la -maxdepth 1opción garantiza que solo busque en el directorio actual (o, si reemplaza el .con alguna ruta, ese directorio). Si desea una lista recursiva completa de todos los archivos en ese y subdirectorios, simplemente elimine esa opción.

carlpett
fuente
Después de mi comentario a la respuesta de mklement0, me di cuenta de que "find ./*.png -maxdepth 1 -type f> pngs.txt" probablemente lograría lo mismo. Lo hace. Sin instalar un script.
Alex Hall
2
finden mac, no tiene -typeni -maxdepthopciones.
Timofey
1
@Tim: -typey -maxdepthno son opciones en el sentido normal; BSD find(como se usa en OS X) los llama primarios , y deben ir después del operando (s) del nombre de archivo ( ., en este caso, tenga en cuenta que, a diferencia de Linux, la versión BSD necesita al menos un operando de nombre de archivo explícito); el comando en esta respuesta definitivamente funciona en una Mac.
mklement0
1
@AlexHall: Esa es una solución inteligente (aunque sugiero find *.png -maxdepth 0 -type fevitar el ./prefijo en los nombres de los archivos de salida; también tenga en cuenta el -maxdepthde 0, no 1), siempre que todo lo que necesite sean los nombres de los archivos en orden alfabético . Si desea lo lsque de otra manera puede hacer por usted (formato / orden de salida diferente, control en línea sobre si los elementos ocultos están incluidos o no), complementado con filtrado de [múltiples] tipos, el script de mi respuesta puede ayudar.
mklement0
1
Para contrastar find * -maxdepth 0 -type f(una alternativa derivada del comentario de @ AlexHall) con find . -maxdepth 1 -type fla respuesta: find . ...invariablemente incluye elementos ocultos, invariablemente antepone los nombres de archivo de salida ./y, con GNU find(Linux), generalmente genera una lista sin clasificar. find * ..., debido a que permite que el shell realice un globbing por adelantado, excluye de forma predeterminada los elementos ocultos (se puede cambiar con shopt -s dotglob), genera meros nombres de archivo (sin prefijo), ordenados alfabéticamente. Ninguno de los enfoques incluye enlaces simbólicos a archivos; use la opción -Lpara hacerlo.
mklement0
14
ls -p | grep -v /

ls -p le permite mostrar / después del nombre de la carpeta, que actúa como una etiqueta que puede eliminar.

Dr_Hope
fuente
Es bueno ver un ejemplo usando lsademás de find, ya que el último devuelve rutas relativas y el primero solo nombres de archivo. Utilice la herramienta adecuada para el trabajo.
Ben Amos
5
  • findanswer ( find . -maxdepth 1 -type f) basado en carlpett funciona en principio, pero nols./ls es exactamente lo mismo que usar : obtienes una lista potencialmente desordenada de nombres de archivos con el prefijo y pierdes la capacidad de aplicar las muchas opciones ;
    también find invariablemente también encuentra elementos ocultos , mientras que lsel comportamiento depende de la presencia o ausencia de las opciones -ao -A.

    • Una mejora , sugerida por Alex Hall en un comentario sobre la pregunta, es combinar el globbing de caparazones confind :

          find * -maxdepth 0 -type f  # find -L * ... includes symlinks to files
      
      • Sin embargo, aunque esto soluciona el problema del prefijo y le brinda una salida ordenada alfabéticamente , aún no tiene control (en línea) sobre la inclusión de elementos ocultos ni acceso a lsmuchas otras opciones de clasificación / formato de salida.
  • La respuesta de Hans Roggeman ls+grep es pragmática, pero lo bloquea para usar el -lformato de salida largo ( ) .


Para hacer frente a estas limitaciones que escribió el fls( f iltering ls ) de utilidad ,

  • una utilidad que proporciona la flexibilidad de salida dels al mismo tiempo que proporciona capacidad de filtrado de tipos ,
  • simplemente colocando caracteres de filtrado de tipo, como farchivos, ddirectorios y lenlaces simbólicos antes de una lista de lsargumentos (ejecutar fls --helpo fls --manpara obtener más información).

Ejemplos:

fls f        # list all files in current dir.
fls d -tA ~  #  list dirs. in home dir., including hidden ones, most recent first
fls f^l /usr/local/bin/c* # List matches that are files, but not (^) symlinks (l)

Instalación

Plataformas compatibles

  • Al instalar desde el registro npm : Linux y macOS
  • Al instalar manualmente : cualquier plataforma similar a Unix con Bash

Desde el registro npm

Nota: Incluso si no usa Node.js, su administrador de paquetes npmfunciona en todas las plataformas y es fácil de instalar; tratar
curl -L https://git.io/n-install | bash

Con Node.js instalado, instale de la siguiente manera:

[sudo] npm install fls -g

Nota :

Instalación manual

  • Descargue este bashscript como fls.
  • Hazlo ejecutable con chmod +x fls.
  • Muévalo o enlace simbólico a una carpeta en su $PATH, como /usr/local/bin(macOS) o /usr/bin(Linux).
mklement0
fuente
1
Brillante. Incluso si implica la creación de otro guión. Copié y pegué desde la fuente de texto sin formato a la que enlaza, en un archivo de texto, y lo ejecuté en Cygwin con este comando: fls.sh f * .png> pngs.txt Y bingo: una lista de archivos .png sin rutas. Pero realmente, ¿ls no tiene una opción comparable al modificador "dir / b" de DOS? Revisé el contenido de la salida de ayuda de ls, y al menos no hay nada por el estilo.
Alex Hall
1
@AlexHall: Gracias; tl; dr: try -1(el número uno); lsen realidad, el valor predeterminado es la salida "desnuda", es decir, sólo nombres de archivo, pero cuando se envía a un terminal utiliza un diseño basado en columnas (varios nombres de archivo por línea). Para obtener un nombre de archivo por línea de salida (que es lo que dir /bhace, si la memoria funciona), use la -1opción, que en realidad está implícitamente activa cuando stdout no está conectado a una terminal, como cuando se envía a un archivo de salida o tubería.
mklement0
2

Listado del contenido de algún directorio, sin subdirectorios

Me gusta usar lsopciones, por ejemplo:

  • -l utilizar un formato de lista larga
  • -t ordenar por hora de modificación, las más recientes primero
  • -r orden inverso al ordenar
  • -F, --classify añadir indicador (uno de * / => @ |) a las entradas
  • -h, --human-readable con -l y -s, tamaños de impresión como 1K 234M 2G, etc.

Alguna vez --colory todas las demás. (Ver ls --help)

Listado de todo menos carpetas

Esto mostrará archivos, enlaces simbólicos, dispositivos, tuberías, sockets, etc.

entonces

find /some/path -maxdepth 1 ! -type d

se podría ordenar por fecha fácilmente:

find /some/path -maxdepth 1 ! -type d -exec ls -hltrF {} +

Listado de archivos solamente:

o

find /some/path -maxdepth 1 -type f

ordenados por tamaño:

find /some/path -maxdepth 1 -type f -exec ls -lSF --color {} +

Evite la lista de entradas ocultas :

Para no mostrar entradas ocultas, donde el nombre comienza con un punto, puede agregar ! -name '.*':

find /some/path -maxdepth 1 ! -type d ! -name '.*' -exec ls -hltrF {} +

Entonces

Puede reemplazar /some/pathpor .para listar para el directorio actual o ..para el directorio principal .

F. Hauri
fuente
1

También puede usar lscon grepo egrepy ponerlo en su perfil como un alias:

ls -l | egrep -v '^d'
ls -l | grep -v '^d'
Hans Roggeman
fuente
No pondría esto en un script por la razón dada anteriormente, pero otra solución rápida y sucia: ls -F | grep -v '/ $'
mooie
1

buscar archivos: ls -l / home | grep "^ -" | tr -s '' | cortar -d '' -f 9

buscar directorios: ls -l / home | grep "^ d" | tr -s '' | cortar -d '' -f 9

buscar enlaces: ls -l / home | grep "^ l" | tr -s '' | cortar -d '' -f 9

tr -s '' convierte la salida en un archivo delimitado por espacios, el comando de corte dice que el delimitador es un espacio y devuelve el noveno campo (siempre el nombre de archivo / nombre de directorio / nombre de enlace).

¡Uso esto todo el tiempo!

Ricardo
fuente
¡Guauu! ¿Qué pasa si los nombres de archivo contienen espacios?
F. Hauri
0
{ find . -maxdepth 1 -type f | xargs ls -1t | less; }

agregado xargspara que funcione, y se usa en -1lugar de -lmostrar solo nombres de archivo sin lsinformación adicional

Anabioz
fuente
Esto tiene cierto mérito, ya que impone la clasificación por tiempo, aunque podría decirse que hay formas menos torpes de hacer esofind -printf0 '...' | sort -z
tripleee
-2

Solo agrego a la respuesta de carlpett. Para una vista más útil de los archivos, puede canalizar la salida a ls.

find . -maxdepth 1 -type f|ls -lt|less

Muestra los archivos modificados más recientemente en un formato de lista, bastante útil cuando ha descargado muchos archivos y desea ver una versión ordenada de los más recientes.

Abhay
fuente
3
¡Esto probablemente no se comporte como esperabas! lsno lee la entrada estándar, por lo que es inútil canalizar nada a ls. ¿Se ha perdido xargs?
gniourf_gniourf
Para decirlo de otra manera: el findcomando en esta respuesta se ignora por completo ; el comando general es el mismo que ls -lt | less, que no realiza ningún filtrado de tipo.
mklement0
1
Aunque con GNU findpodrías hacerlo find . -maxdepth 1 -type f -ls. También parece que funciona en Mac OS, aunque creo -maxdepthy -lsno están debidamente opciones portátiles.
tripleee
-2

"find '-maxdepth'" no funciona con mi versión anterior de bash, por lo tanto, uso:

para f en $ (ls); hacer si [-f $ f]; luego echo $ f; fi; hecho

Gill Davison
fuente
El uso de for f in $(ls) es doblemente incorrecto. Podrías arreglar eso con for f in *pero luego se rompería porque no estás citando el argumento echocorrectamente.
tripleee