in

directorio: ¿enumerar solo directorios que usan ls en Bash?

apple touch icon@2

Cuatro (más) opciones confiables.

Un no cotizado asterisco * será interpretado como un patrón (glob) por el shell. El shell lo usará en la expansión del nombre de ruta. Luego generará una lista de nombres de archivo que coinciden con el patrón.

Un simple asterisco coincidirá con todos los nombres de archivo en el PWD (directorio de trabajo actual). Un patrón más complejo como */ coincidirá con todos los nombres de archivo que terminan en /. Por lo tanto, todos los directorios. Por eso el comando:

echo */
echo ./*/              ### Avoid misinterpreting filenames like "-e dir"

será expandido (por el shell) a echo todos los directorios de la PWD.


Para probar esto: Cree un directorio (mkdir) nombrado como test-dir, y cd en ello:

mkdir test-dir; cd test-dir

Crea algunos directorios:

mkdir {cs,files,masters,draft,static}   # Safe directories.
mkdir {*,-,--,-v var,-h,-n,dir with spaces}  # Some a bit less secure.
touch -- 'file with spaces' '-a' '-l' 'filename'    # And some files:

El comando echo ./*/ seguirá siendo confiable incluso con archivos con nombres impares:

./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/
./masters/ ./-n/ ./static/ ./-v var/

Pero los espacios en los nombres de los archivos hacen que la lectura sea un poco confusa.


Si en lugar de echo, usamos ls. El shell sigue siendo lo que amplía la lista de nombres de archivos. El shell es la razón para obtener una lista de directorios en el PWD. los -d opción a ls hace que enumere la entrada del directorio actual en lugar del contenido de cada directorio (como se presenta por defecto).

ls -d */

Sin embargo, este comando es (algo) menos confiable. Fallará con los archivos con nombres extraños enumerados anteriormente. Se ahogará con varios nombres. Necesita borrar uno por uno hasta encontrar los que tienen problemas.

El GNU ls aceptará el «fin de opciones» (--) llave.

ls -d ./*/                     ### More reliable BSD ls
ls -d -- */                    ### More reliable GNU ls

Para enumerar cada directorio en su propia línea (en una columna, similar a ls -1), use:

$ printf "%sn" */        ### Correct even with "-", spaces or newlines.

Y, mejor aún, podríamos eliminar el final /:

$ set -- */; printf "%sn" "${@%/}"        ### Correct with spaces and newlines.

Un intento como

$ for i in $(ls -d */); do echo ${i%%/}; done

fallará en:

  • algunos nombresls -d */) como ya se muestra arriba.
  • se verá afectado por el valor de IFS.
  • dividirá los nombres en espacios y pestañas (con valores predeterminados IFS).
  • cada nueva línea en el nombre iniciará un nuevo comando de eco.

Finalmente, el uso de la lista de argumentos dentro de una función no afectará la lista de argumentos del actual shell en ejecución. Simplemente

$ listdirs(){ set -- */; printf "%sn" "${@%/}"; }
$ listdirs

presenta esta lista:

--
-
*
cs
dir with spaces
draft
files
-h
masters
-n
static
-v var

Estas opciones son seguras con varios tipos de nombres de archivo extraños.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

60 230655 1575021953

¿Cómo instalo MySQLdb en Python?

ciXLNWmrdgT3LGBbznQHUg 1200 80

God of War no se detendrá con la mitología nórdica: prepárate también para los lugares del antiguo Egipto y los mayas