¿Cómo devuelvo solo los nombres de archivo del comando find?

13

Estoy buscando obtener una lista de solo nombres de archivo (sin el resto de la ruta) al ejecutar el comando find desde una terminal. ¿Cómo logro esto en Mac?

blueberryfields
fuente

Respuestas:

17

Con nombre base:

find . -type f -exec basename {} \;

Paulo Almeida
fuente
¿Para qué sirven las llaves?
nullpotent
basename se ejecuta una vez por cada archivo encontrado, denotado por {}.
Ярослав Рахматуллин
¿Cuál es la media de \ y; ?
neouyghur
@neouyghur ;termina la -execacción. El \ es necesario porque ;también tiene un significado especial para el shell.
8bittree
6

Evilsoup mencionó que lo publicado no funciona para nombres de archivos espaciados. Entonces, en su lugar, podría usar:

find . -type f -print0 | while IFS= read -r -d '' filename; do echo ${filename##*/}; done
nerdwaller
fuente
Esto se romperá en archivos con espacios en sus nombres (ver análisis de ls en el wiki de greg)
evilsoup
+1 por velocidad. No sé si hice algo mal, pero este tomó 1 segundo en mi $ HOME, mientras que todos los demás tomaron alrededor de 10 segundos. Por supuesto, necesitaría más de 10 segundos para buscar esto y escribirlo.
Paulo Almeida
2

Con GNU find, puedes hacer:

 find ~/tmp/ -printf "%f\n"

Probablemente valga la pena intentarlo también en OS X.

Ярослав Рахматуллин
fuente
2
-printfNo se admite en BSD de OS X find.
Daniel Beck
1
Además, -printftiene poca relación con la printfutilidad de shell C o POSIX printf. El uso de este nombre de función histórica para algo diferente es muy poco considerado. Los chicos conservadores de BSD probablemente lo vean de la misma manera, por lo que probablemente no veremos un clon -printfen el hallazgo de BSD, bajo ese nombre.
Kaz
No estoy de acuerdo con que se considere mal usar un nombre de función familiar para realizar una tarea similar en un contexto diferente. Por qué BSD probablemente nunca lo admitirá es otra cuestión.
Ярослав Рахматуллин
2

Hay una mejor manera de eliminar todo menos la última parte de una ruta de archivo; con awk Es mejor porque awk no se ejecuta una vez para cada archivo. En algunos casos esto importa.

find ~/tmp/ -type f  | awk -F/ '{ print $NF }'

Solo buscamos archivos en ~ / tmp y obtenemos una lista donde cada entrada está separada por barras. Por lo tanto, utilizamos una barra como separador de campo (-F /) e imprimimos el parámetro de campo ($ 1 .. $ 9) que corresponde al último campo ($ NF).

Ярослав Рахматуллин
fuente
Este es el más rápido que probé.
Paulo Almeida
He estado usando Cygwin últimamente, y crear un proceso en Windows es muy costoso ...
Ярослав Рахматуллин
2

EDITAR :

Utilizando sed:

$ find . -type f | sed 's/.*\///'

Usando el comando xargs , como se menciona en la respuesta de @nerdwaller

$ find . -type f -print0 | xargs --null -n1 basename
stderr
fuente
1
Gracias por señalarlo, +1, no he usado mucho xargs ... Definitivamente debería hacerlo ya que eliminaste bastantes caracteres de mi comando.
nerdwaller
Este se rompe cuando los archivos tienen espacios. Funciona así, al menos en una prueba rápida:find . -type f -print0| xargs --null -n1 basename
Paulo Almeida
Ninguno de los dos --nullo de -n1opciones está disponible en OSX
Valeriy Van
1

¿Qué hay de esto?

find … | egrep -o -e '[^/]+$'

Ventaja: solo se genera exactamente un proceso adicional, no uno por cada resultado.

David Foerster
fuente
0

Puede llamar shdesde la -execopción de búsqueda y evitar el uso de tuberías innecesarias. Esto también tiene la ventaja de que no necesita preocuparse por nombres de archivos divertidos (espacios, líneas nuevas, etc.):

find . -type f -exec sh -c 'echo "${0##*/}"' {} \;
maldad
fuente