scripts script resueltos programas pasar parametros operaciones manejo ejercicios ejemplos comandos cadenas aritmeticas bash directory ls

resueltos - scripts bash ejemplos



Listado solo directorios usando ls en bash: un examen (22)

Este comando lista los directorios en la ruta actual: ls -d */

¿Qué hace exactamente el patrón */ hacer?

¿Y cómo podemos dar la ruta absoluta en el comando anterior (por ejemplo, ls -d /home/alice/Documents ) para listar solo los directorios en esa ruta?


Solución real de ls , incluyendo enlaces simbólicos a directorios.

Muchas respuestas aquí en realidad no usan ls (o solo se usan en el sentido trivial de ls -d , mientras que se usan comodines para la coincidencia del subdirectorio real. Una solución ls verdadera es útil, ya que permite el uso de las opciones de ls para el orden de clasificación , etc.

Excluyendo enlaces simbólicos

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 entubando sed o awk para aislar los nombres de los archivos)

Incluyendo enlaces simbólicos

En el caso (probablemente más común) de que deben incluirse enlaces simbólicos a directorios, podemos usar la opción -p de ls :

ls -1p | grep ''/$''

o, deshacerse de las barras inclinadas:

ls -1p | grep ''/$'' | sed ''s///$//''

Podemos agregar opciones a ls según sea necesario (si se usa un listado largo, el -1 ya no es necesario).

nota: si queremos barras diagonales al final, pero no las queremos resaltadas con grep , podemos eliminar el resaltado de forma hacker haciendo que la parte coincidente real de la línea esté vacía:

ls -1p | grep -P ''(?=/$)''


Cuatro formas de hacer esto, cada una con un formato de salida diferente

1. usando echo

Ejemplo: echo */ , echo */*/
Aquí está lo que tengo:

cs/ draft/ files/ hacks/ masters/ static/ cs/code/ files/images/ static/images/ static/stylesheets/

2. Usando solo ls

Ejemplo: ls -d */
Aquí es exactamente lo que tengo:

cs/ files/ masters/ draft/ hacks/ static/

O como lista (con información detallada): ls -dl */

3. Usando 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

4. Bash Script (no recomendado para el nombre de archivo contiene espacio).

Ejemplo: for i in $(ls -d */); do echo ${i%%/}; done for i in $(ls -d */); do echo ${i%%/}; done
Aquí está lo que tengo:

cs draft files hacks masters static

Si te gusta 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/


4 (más) opciones confiables.

Un asterisco no citado * será interpretado como un patrón (glob) por el shell.
El shell lo usará en la expansión del nombre de ruta.
Entonces generará una lista de nombres de archivos 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 / .
Así, todos los directorios. Es por eso que el comando:

1.- eco.

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

será expandido (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 nombres impares:

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

Pero los espacios en los nombres de archivos 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 la PWD. La opción -d a ls hace que enumere la entrada del directorio actual en lugar de los contenidos de cada directorio (como se presenta de forma predeterminada).

ls -d */

Sin embargo, este comando es (algo) menos confiable. Se producirá un error con los archivos con nombres impares enumerados anteriormente. Se ahogará con varios nombres. Necesita borrar uno por uno hasta que encuentre los que tienen problemas.

2.- ls

El GNU ls aceptará la tecla "fin de opciones" ( -- ).

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

3.-printf

Para listar 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 rastro / :

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

Un intento como este:

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

Fallará en

  • algunos nombres ( ls -d */ ) como ya se muestra arriba.
  • se verá afectado por el valor de IFS .
  • dividirá los nombres en espacios y tabulaciones (con IFS defecto).
  • Cada nueva línea en el nombre iniciará un nuevo comando de eco.

4.- Función

Finalmente, el uso de la lista de argumentos dentro de una función no afectará la lista de argumentos del shell actual en ejecución. 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 archivos impares.


Acabo de agregar esto a mi archivo .bashrc (también podría 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.


Agregando para completar el círculo, para recuperar la ruta de cada carpeta, usa una combinación de la respuesta de Albert y Gordans que deberían ser bastante ú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/


El comando del tree también es bastante útil aquí. Por defecto, 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 desea 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 -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 diagonales al final, como:

[prompt]$ ls -d */ app// cgi-bin// lib// pub//

probablemente se deba a que, en algún lugar, los archivos de configuración de la shell o de la sesión, alias el comando ls a una versión de ls que incluye el indicador -F. Ese indicador agrega un carácter a cada nombre de salida (que no es un archivo simple) que indica el tipo de cosa que es. Por lo tanto, una barra es la correspondiente al patrón ''* /'' y la otra barra es el indicador de tipo agregado.

Para deshacerse de este problema, podría, por supuesto, definir un alias diferente para ls. Sin embargo, para no invocar temporalmente el alias, puede anteponer el comando con barra invertida:

/ ls -d * /


Esto es lo que estoy usando

ls -d1 /Directory/Path/*;


Para listar solo directorios :

ls -l | grep ^d

para listar solo archivos :

ls -l | grep -v ^d

o también puedes hacer como: ls -ld * /


Para su información, si desea imprimir todos los archivos en multilínea, puede hacer un ls -1 que imprimirá cada archivo en una línea separada. archivo1 archivo2 archivo3


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


Probar si el elemento es un directorio con test -d :

for i in $(ls); do test -d $i && echo $i ; done


Prueba este. esto funcionará en todas las distribuciones ls -ltr | grep drw


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 redujo, la parte mayor :)


Si el directorio oculto no es necesario para ser listado, ofrezco:

ls -l | grep "^d" | awk -F" " ''{print $9}''

Y si se necesitan listados directorios ocultos, use:

ls -Al | grep "^d" | awk -F" " ''{print $9}''

O

find -maxdepth 1 -type d | awk -F"./" ''{print $2}''


Una sola línea para listar directorios solo desde "aquí".

Con el recuento de archivos.

for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done


Utilizando Perl:

ls | perl -nle ''print if -d;''


Yo suelo:

ls -d */ | cut -f1 -d''/''

Esto crea una sola columna sin barra diagonal final, útil en los scripts.

Mis dos centavos.


para mostrar listas de carpetas sin /

ls -d */|sed ''s|[/]||g''


*/ es un patrón de coincidencia de nombre de archivo que coincide con los directorios en el directorio actual.

Para listar solo los 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 -d a* # limit to directories beginning with letter ''a'' llod -d .* # limit to hidden directories

NOTA: se romperá si usas 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'' }


*/ 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 directorios). De manera similar, para enumerar todos los subdirectorios bajo / home / alice / Documents, use ls -d /home/alice/Documents/*/


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

Por encima de la salida se puede refinar más utilizando 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