Este comando enumera directorios en la ruta actual: ls -d */
¿Qué hace exactamente el patrón */
do?
¿Y cómo podemos dar la ruta absoluta en el comando anterior (por ejemplo, ls -d /home/alice/Documents
) para listar solo directorios en esa ruta?
*/
es un patrón que coincide con todos los subdirectorios en el directorio actual ( *
coincidiría con todos los archivos y subdirectorios, el /
restringe a los directorios). Del mismo modo, para enumerar todos los subdirectorios en / home / alice / Documents, use ls -d /home/alice/Documents/*/
echo
Ejemplo: echo */
, echo */*/
Esto es lo que obtuve:
cs/ draft/ files/ hacks/ masters/ static/ cs/code/ files/images/ static/images/ static/stylesheets/
ls
solo Ejemplo: ls -d */
Aquí es exactamente lo que obtuve:
cs/ files/ masters/ draft/ hacks/ static/
O como lista (con información detallada): ls -dl */
ls
y grep
Ejemplo: ls -l | grep "^d"
ls -l | grep "^d"
Esto es lo que obtuve:
drwxr-xr-x 24 h staff 816 Jun 8 10:55 cs drwxr-xr-x 6 h staff 204 Jun 8 10:55 draft drwxr-xr-x 9 h staff 306 Jun 8 10:55 files drwxr-xr-x 2 h staff 68 Jun 9 13:19 hacks drwxr-xr-x 6 h staff 204 Jun 8 10:55 masters drwxr-xr-x 4 h staff 136 Jun 8 10:55 static
Ejemplo: for i in $(ls -d */); do echo ${i%%/}; done
for i in $(ls -d */); do echo ${i%%/}; done
Esto es lo que obtuve:
cs draft files hacks masters static
Si desea tener ‘/’ como carácter final, el comando será: for i in $(ls -d */); do echo ${i}; done
for i in $(ls -d */); do echo ${i}; done
cs/ draft/ files/ hacks/ masters/ static/
Yo suelo:
ls -d */ | cut -f1 -d'/'
Esto crea una sola columna sin barra posterior, útil en las secuencias de comandos.
Mis dos centavos.
Para todas las carpetas sin subcarpetas:
find /home/alice/Documents -maxdepth 1 -type d
Para todas las carpetas con subcarpetas:
find /home/alice/Documents -type d
Un asterisco *
sin comillas 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 archivos que coinciden con el patrón.
Un asterisco simple coincidirá con todos los nombres de archivo en el PWD (presente directorio de trabajo).
Un patrón más complejo como */
coincidirá con todos los nombres de archivo que terminan en /
.
Por lo tanto, todos los directorios. Es por eso que el comando:
echo */ echo ./*/ ### avoid misinterpreting filenames like "-e dir"
se expandirá (por el shell) para hacer echo
todos los directorios en el PWD.
Para probar esto: cree un directorio ( mkdir
) llamado como test-dir y cd
en él:
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 nombre impar:
./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/ ./masters/ ./-n/ ./static/ ./-v var/
Pero los espacios en los nombres de archivo hacen que la lectura sea un poco confusa.
Si en lugar de echo
, usamos ls
, el shell sigue siendo lo que está expandiendo la lista de nombres de archivos. El shell es la razón para obtener una lista de directorios en el PWD. La opción -d
a ls
hace listar la entrada actual del directorio en lugar de los contenidos de cada directorio (como se presenta por defecto).
ls -d */
Sin embargo, este comando es (algo) menos confiable. Fallará con los archivos con nombre impar enumerados arriba. Se ahogará con varios nombres. Tienes que borrar uno por uno hasta que encuentres a los que tienen problemas.
El GNU ls
aceptará la tecla “fin de las opciones” ( --
).
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 "%s\n" */ ### Correct even with "-", spaces or newlines.
Y, aún mejor, podríamos eliminar el final /
:
$ set -- */; printf "%s\n" "${@%/}" ### Correct with spaces and newlines.
Un bash como este:
$ for i in $(ls -d */); do echo ${i%%/}; done
Fallará en:
ls -d */
) como ya se mostró arriba. IFS
. IFS
predeterminado). Finalmente, el uso de la lista de argumentos dentro de una función no afectará a la lista de argumentos del shell en ejecución actual. Simplemente:
$ listdirs(){ set -- */; printf "%s\n" "${@%/}"; } $ 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 impares.
El comando de tree
también es bastante útil aquí. De forma predeterminada, mostrará todos los archivos y directorios a una profundidad completa, con algunos caracteres ascii que muestran el árbol de directorios.
$ tree . ├── config.dat ├── data │ ├── data1.bin │ ├── data2.inf │ └── sql | │ └── data3.sql ├── images │ ├── background.jpg │ ├── icon.gif │ └── logo.jpg ├── program.exe └── readme.txt
Pero si quisiéramos obtener solo los directorios, sin el árbol ascii, y con la ruta completa desde el directorio actual, podría hacer:
$ tree -dfi . ./data ./data/sql ./images
Los argumentos son:
-d List directories only. -f Prints the full path prefix for each file. -i Makes tree not print the indentation lines, useful when used in conjunction with the -f option.
Y si luego quiere la ruta absoluta, puede comenzar especificando la ruta completa al directorio actual:
$ tree -dfi "$(pwd)" /home/alice/Documents /home/alice/Documents/data /home/alice/Documents/data/sql /home/alice/Documents/images
Y para limitar el número de subdirectorios, puede establecer el nivel máximo de subdirectorios con el -L level
, por ejemplo:
$ tree -dfi -L 1 "$(pwd)" /home/alice/Documents /home/alice/Documents/data /home/alice/Documents/images
Se pueden ver más argumentos con el árbol del hombre
En caso de que se esté preguntando por qué la salida de ‘ls -d * /’ le da dos barras inclinadas, como:
[prompt]$ ls -d */ app// cgi-bin// lib// pub//
es probable que se deba a que en algún lugar los archivos de configuración de su shell o sesión alias tienen el comando ls en una versión de ls que incluye el distintivo -F. Esa bandera agrega un carácter a cada nombre de salida (que no es un archivo simple) que indica el tipo de cosa que es. De modo que una barra oblicua es la que coincide con el patrón ‘* /’, y la otra barra inclinada es el indicador de tipo adjunto.
Para deshacerte de este problema, por supuesto podrías definir un alias diferente para ls. Sin embargo, para no invocar temporalmente el alias, puede anteponer el comando con la barra diagonal inversa:
\ ls -d * /
Acabo de agregar esto a mi archivo .bashrc
(también podría simplemente escribirlo en la línea de comandos si solo lo necesita / desea para una sesión)
alias lsd='ls -ld */'
entonces lsd producirá el resultado deseado.
Si el directorio oculto no es necesario para ser enumerado, ofrezco:
ls -l | grep "^d" | awk -F" " '{print $9}'
Y si se necesitan directorios ocultos para ser enumerados, use:
ls -Al | grep "^d" | awk -F" " '{print $9}'
O
find -maxdepth 1 -type d | awk -F"./" '{print $2}'
para mostrar listas de carpetas sin /
ls -d */|sed 's|[/]||g'
Esto es lo que estoy usando
ls -d1 /Directory/Path/*;
ls
real, incluidos enlaces simbólicos a directorios Muchas respuestas aquí en realidad no usan ls
(o solo lo usan en el sentido trivial de ls -d
, mientras usan comodines para la coincidencia real de subdirectorios. Una verdadera solución de ls
es útil, ya que permite el uso de opciones de ls
para ordenar el orden , etc.
Se ha dado una solución que usa ls
, pero hace algo diferente de las otras soluciones en que excluye enlaces simbólicos a directorios:
ls -l | grep '^d'
(posiblemente pasando por sed
o awk
para aislar los nombres de los archivos)
En el caso (probablemente más común) de que se incluyan enlaces simbólicos a directorios, podemos usar la opción -p
de ls
:
ls -1p | grep '/$'
o, deshacerse de las barras posteriores:
ls -1p | grep '/$' | sed 's/\/$//'
Podemos agregar opciones a ls
según sea necesario (si se usa una lista larga, el -1
ya no es necesario).
Nota: si queremos barras diagonales posteriores, pero no queremos que sean resaltadas por grep
, podemos eliminar el resaltado de forma fraudulenta haciendo que la parte correspondiente de la línea quede vacía:
ls -1p | grep -P '(?=/$)'
Pruebe si el elemento es un directorio con test -d
:
for i in $(ls); do test -d $i && echo $i ; done
One-liner para listar directorios solo desde “aquí”.
Con el conteo de archivos.
for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done
*/
es un patrón de coincidencia de nombre de archivo que coincide con los directorios en el directorio actual.
Para enumerar solo directorios, me gusta esta función:
# long list only directories llod () { ls -l --color=always "$@" | grep --color=never '^d' }
Ponlo en tu .bashrc.
Ejemplos de uso:
llod # long listing of all directories in current directory llod -tr # same but in chronological order oldest first llod -da* # limit to directories beginning with letter 'a' llod -d .* # limit to hidden directories
NOTA: se romperá si usa la opción -i
. Aquí hay una solución para eso:
# long list only directories llod () { ls -l --color=always "$@" | egrep --color=never '^d|^[[:digit:]]+ d' }
FYI, si desea imprimir todos los archivos en varias líneas, puede hacer un ls -1
que imprimirá cada archivo en una línea separada. archivo1 archivo2 archivo3
Usando Perl:
ls | perl -nle 'print if -d;'
Lo resolví parcialmente con:
cd "/path/to/pricipal/folder" for i in $(ls -d .*/); do sudo ln -s "$PWD"/${i%%/} /home/inukaze/${i%%/}; done ln: «/home/inukaze/./.»: can't overwrite a directory ln: «/home/inukaze/../..»: can't overwrite a directory ln: accesing to «/home/inukaze/.config»: too much symbolics links levels ln: accesing to «/home/inukaze/.disruptive»: too much symbolics links levels ln: accesing to «/home/inukaze/innovations»: too much symbolics links levels ln: accesing to «/home/inukaze/sarl»: too much symbolics links levels ln: accesing to «/home/inukaze/.e_old»: too much symbolics links levels ln: accesing to «/home/inukaze/.gnome2_private»: too much symbolics links levels ln: accesing to «/home/inukaze/.gvfs»: too much symbolics links levels ln: accesing to «/home/inukaze/.kde»: too much symbolics links levels ln: accesing to «/home/inukaze/.local»: too much symbolics links levels ln: accesing to «/home/inukaze/.xVideoServiceThief»: too much symbolics links levels
Bueno, esto me reduce, la parte principal 🙂
Para completar el círculo, para recuperar la ruta de cada carpeta, use una combinación de la respuesta de Albert y Gordans que deberían ser muy útiles.
for i in $(ls -d /pathto/parent/folder/*/); do echo ${i%%/}; done
Salida:
/pathto/parent/folder/childfolder1/ /pathto/parent/folder/childfolder2/ /pathto/parent/folder/childfolder3/ /pathto/parent/folder/childfolder4/ /pathto/parent/folder/childfolder5/ /pathto/parent/folder/childfolder6/ /pathto/parent/folder/childfolder7/ /pathto/parent/folder/childfolder8/
Prueba este. esto funcionará en todas las distribuciones ls -ltr | grep drw
Para enumerar solo directorios :
ls -l | grep ^d
para listar solo archivos :
ls -l | grep -v ^d
o también puedes hacer lo siguiente: ls -ld * /
file *|grep directory
O / P (en mi máquina) –
[root@rhel6 ~]# file *|grep directory mongo-example-master: directory nostarch: directory scriptzz: directory splunk: directory testdir: directory
La salida anterior puede refinarse más usando corte.
file *|grep directory|cut -d':' -f1 mongo-example-master nostarch scriptzz splunk testdir * could be replaced with any path that's permitted file - determine file type grep - searches for string named directory -d - to specify a field delimiter -f1 - denotes field 1