Bash: ls * sin agrupación de carpetas

12

Si escribo:

ls source/*

source/fonts:
fontello

source/images:
bg1.png                eng.png        fra.png   

Obtengo la lista de archivos, agrupados por nombres de carpeta. ¿Cómo puedo simplemente obtener la lista de nombres de archivo?

ls source/*

source/fonts/fontello
source/images/bg1.png
source/images/eng.png
source/images/fra.png   

Gracias

Augustin Riedinger
fuente
Si esto es para uso de secuencias de comandos, es posible que desee ver mywiki.wooledge.org/ParsingLs . (Dicho esto, también hay formas de usar findmal; particularmente, si estás corriendo for file in $(find ...), has golpeado uno de ellos).
Charles Duffy

Respuestas:

13

No parece posible sin la alteración de la salida, pero aquí hay una forma alternativa fácil:

find source/ -type f

O (específico para GNU find), solo para obtener archivos en la profundidad de su pregunta:

find source/ -type f -mindepth 2 -maxdepth 2

(o si desea directorios como el que lsle da, elimine -type f)

maxxvw
fuente
5

Simplemente puede apegarse a ls si agrega algunos psychedlics ( ls -d):

# mkdir test
# cd test
# mkdir A B C
# touch {A,B,C}/file*
# ls -d */*    
A/file  B/file  C/file
ikrabbe
fuente
@Cthulhu ok, mi ejemplo es demasiado corto. Si tiene carpetas en A, B a / o C, -d ayuda a mostrar solo lo que seleccionó. En realidad no me gusta encontrar y puedes definir la profundidad por el argumento con ls -d
ikrabbe
He sugerido una edición a la otra respuesta para limitar la profundidad.
o11c
@ o11c muy bueno, pero sigue findsiendo una bestia gorda.
ikrabbe
3

Te puede interesar "el hombre pobre find":

shopt -s globstar

shopt -s establece las opciones de shell con nombre. La globstaropción se define como sigue en bash (1) :

Si se establece, el patrón **utilizado en un contexto de expansión de nombre de archivo / ruta coincidirá con un archivo [sic] y cero o más directorios y subdirectorios. Si el patrón es seguido por a /, solo coinciden los directorios y subdirectorios.

Entonces, después de haberlo hecho shopt -s globstar, cualquiera de los siguientes comandos:

ls -d1 - fuente / **                  # El carácter después de la 'd' es el dígito uno. 
ls -d - fuente / ** | cat             # es decir, lo escribirá en una tubería a cualquier comando. 
printf "% s \ n" fuente / **

producirá la salida:

source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png

Desafortunadamente, esto también incluye los nombres de directorio. Podría ayudarte un poco saber que

printf "%s\n" source/**/

producirá la salida:

source/
source/fonts
source/images

es decir, solo los nombres de directorio. Es posible redirigir la salida de uno de la primera serie de comandos a un archivo, redirigir la salida de los anteriores a un segundo archivo, y luego usar comm, diffo algo similar, para restar el segundo archivo desde la primera, dejando sólo la llanura archivos (no directorios). Pero no hagas eso.

Otro enfoque (que no es mucho mejor) es

ls -d --file-type -- source/** | grep -v '/$'

La --file-typeopción le indica lsque muestre un / al final de cada nombre de directorio (y otros caracteres al final de otros tipos de archivos (especiales)), como este:

fuente //                             # Se agregó una 
fuente / fuentes adicionales /                        # Se agregó una
fuente / fuentes / fontello
fuente / imágenes /                       # Agregado uno
fuente / imágenes / bg1.png
fuente / images / eng.png
fuente / images / fra.png

y luego grep -v '/$'elimina las líneas que terminan con /; es decir, los nombres de directorio. Desafortunadamente, POSIX--file-type no especifica la opción . Si su versión de lsno lo admite, úselo -F. Es como, --file-type excepto que también muestra un *al final de los nombres de los archivos ejecutables, lo que algunas personas encuentran molesto. Puedes eliminarlos con sed:

ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'

Si desea hacer algo con todos los archivos (y solo los archivos), puede hacerlo

para f en fuente / **
hacer
    si [-f "$ f"]
    luego
        Inserte los comandos que se aplicarán a los archivos sin formato aquí.
    fi
hecho

Notas:

  • Cuando lsestá dando salida a un terminal, y no es en -l( l modo de ong), escribe varios nombres por línea (a menos que los nombres son muy largos). Puede forzarlo a escribir un nombre por línea especificando -1(uno) o redirigiendo la salida a un archivo o una tubería.
  • Probablemente no necesite realmente --los lscomandos ya que está enumerando un directorio cuyo contenido creó. Debe usarlo cuando se enumera *en un directorio desconocido, como protección contra los nombres de archivo que comienzan con -.
  • No intente analizar la salida de ls.
  • La globstaropción de shell parece no estar definida por POSIX. (De hecho, no estoy seguro de que POSIX reconozca las opciones de shell). Si bien parece ser un bashismo, tenga cuidado, puede que no esté presente en todas las versiones de bash.
  • Si fontso imagestiene subdirectorios, **mostrará una lista de todos ellos, de forma recursiva, hasta el fondo. Una forma (algo confusa y poco confiable) de limitar la profundidad es

    ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
    

    que elimina líneas que contienen tres o más /caracteres.

Scott
fuente