Obtenga una lista de nombres de directorio con find

35

Sé que puedo hacer esto para obtener una lista de nombres de directorio:

find . -type d -maxdepth 1 

El resultado se ve así:

.
./foo
./bar

Prefiero el listado sin ./. ¿Hay alguna manera de hacer que find solo muestre los nombres sin formato?

Intenté enviar la lista a stat para formatearla, pero eso me da el mismo resultado:

find . -type d -maxdepth 1 -print0 | xargs -0 stat -f '%N'
joachim
fuente
entonces quieres foo bar ...todo en una línea sin el ./frente?
Levon
¿Es esto solo por razones cosméticas / estéticas o está tratando de hacer algo con la salida?
jw013

Respuestas:

42

Con GNU findpuedes usar la -printfopción:

find . -maxdepth 1 -type d -printf '%f\n'

Como señaló Paweł en los comentarios, si no desea que se agregue el directorio actual -mindepth 1, agregue , por ejemplo:

find . -mindepth 1 -maxdepth 1 -type d -printf '%f\n'
Thor
fuente
No puedo encontrar ninguna mención de la -printfopción en la última especificación POSIX y me pregunto cómo portátil es ...
rahmu
@rahmu: Esto fue probado con GNU find. printfPOSIX no menciona ninguna de las opciones y no parece ser compatible con algunas de las otras findversiones. GNU find se puede instalar en la mayoría de los lugares, por lo que en ese sentido es portátil.
Thor
1
agregue también -mindepth 1si desea deshacerse del.
Paweł Prażak
18

Actualizar:

Una alternativa más corta:

 find . -maxdepth 1 -type d | cut -c 3-

Le dará los nombres, uno por línea, sin barras.

Levon
fuente
44
@downvoter .. un voto negativo sin explicación no ayuda a nadie (OP, SO o yo). Esta es una solución funcional a la pregunta de OP. Me complace corregir un error si se señala o mejorar la respuesta, pero eso requiere comentarios constructivos en lugar de un simple "clic" anónimo.
Levon
1
Yo fui quien votó en contra cuando su respuesta incluyó el análisis ls. Al mismo tiempo, había publicado un enlace sobre por qué esta es una mala idea en otra respuesta que se eliminó desde entonces. En ese momento solo había 2 respuestas y la razón parecía obvia. Me alegra que hayas señalado la ambigüedad, y aquí está mi explicación. Para el registro, convertí mi voto a favor en un voto a favor porque estoy de acuerdo con su respuesta actual.
rahmu
@rahmu Dar una explicación de su voto negativo en otra pregunta no me ayuda (y solo es obvio para usted). Además, si bien esta es una mejor solución, la solución que había publicado antes funcionó bien (sí, estoy familiarizado con su enlace "no use ls", pero no se aplica a ciegas en todos los casos). Si tiene un contraejemplo de por qué mi solución inicial no hubiera funcionado, me encantaría saberlo (para que realmente pueda aprender algo de esto), de lo contrario, solo está publicando un enlace y no ofrece nada constructivo.
Levon
Considere que hay un \nnombre en un directorio que no puede usar cut para recuperarlo (que es lo que estaba haciendo cuando lo rechacé). Hay pocos casos en los lsque no se comporta de manera peligrosa y casi siempre es más seguro usarlo de otra manera.
rahmu
9

Usando GNU find, puede usar -mindepth para evitar que find coincida con el directorio actual:

find . -type d -maxdepth 1 -mindepth 1

Como no estás haciendo esto de forma recursiva, puedes usar un bash glob:

echo */

Agregar un final / a un glob hará que solo coincidan los directorios.

jordanm
fuente
1
*/pierde archivos de puntos e incluye enlaces simbólicos. Esto puede o no ser un problema.
Gilles 'SO- deja de ser malvado'
@Gilles: siempre perderá enlaces simbólicos, pero los archivos de puntos dependen de si dotglob está o no configurado.
jordanm
6

Deja sedeliminar esos dos caracteres:

find . -maxdepth 1 -type d | sed -e 's/^\.\///'
Birei
fuente
6

Prefiero usar:

 find ./ -type d -maxdepth 1 -exec basename {} \;
usuario1293137
fuente
2

Usualmente uso:

find * -type d

Pero no sé si es la forma correcta de hacer lo que quieres.

Francesco Turco
fuente
1
Si va a dejar que el shell expanda todos los nombres de archivo, ¿por qué usar find?
jordanm
@jordanm Para seleccionar solo directorios. echo */haría lo mismo, más o menos (pierde archivos de puntos e incluye enlaces simbólicos), pero luego Joaquín le preguntaría cómo eliminar el final /.
Gilles 'SO- deja de ser malvado'
0

En AIX, el parámetro 'maxdepth' no funciona.

En general, esto funciona para mí:

find ./ -type d | cut -d"/" -f2 | sort -u

usuario1656294
fuente
0

Lo que está buscando se llama basename, ignora la estructura de directorios de Unix.

Ejemplo a continuación:

find /any/path/you/want -maxdepth 1 -type d -exec basename {} \;

excluirá para la salida incluso la ruta del directorio, eliminando la necesidad de cd ejecutar el comando antes


Alguna información adicional:

Pasaría -execcomo argumento para encontrar en su lugar |(canalizar) otro comando para la salida (evitando que el segundo comando pase por cada línea de salida, habiendo dicho eso, dependiendo de la salida podría mejorar el rendimiento del script)

NOTA: las findopciones no son posicionales (-maxdepth afecta las pruebas especificadas antes y las especificadas después).

gonzalesraul
fuente