Como faço para retornar apenas nomes de arquivos do comando find?

13

Estou procurando obter uma lista de apenas nomes de arquivos (sem o resto do caminho) ao executar o comando find a partir de um terminal. Como faço para fazer isso no mac?

blueberryfields
fonte

Respostas:

17

Com nome de base:

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

Paulo Almeida
fonte
Para que servem os chavetas?
Nulopotent 17/07/2013
basename é executado uma vez para cada arquivo encontrado, indicado por {}.
Ярослав Рахматуллин
qual é a média do \ e; ?
neouyghur
@neouyghur ;finaliza a -execação. O \ é necessário porque ;também tem um significado especial para o shell.
precisa saber é o seguinte
6

Evilsoup mencionou que o que foi postado não funciona para nomes de arquivos espaçados. Então, em vez disso, você pode usar:

find . -type f -print0 | while IFS= read -r -d '' filename; do echo ${filename##*/}; done
nerdwaller
fonte
Isso vai quebrar em arquivos com espaços em seus nomes (ver análise de ls na wiki de Greg)
evilsoup
+1 para velocidade. Não sei se fiz algo errado, mas este levou 1 segundo no meu $ HOME, enquanto todos os outros levaram cerca de 10 segundos. Claro, eu precisaria de mais de 10 segundos para pesquisar e digitar.
Paulo Almeida
2

Com o GNU find, você pode:

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

Provavelmente vale a pena tentar no OS X também.

Ярослав Рахматуллин
fonte
2
-printfnão é compatível com BSD do OS X find.
Daniel Beck
1
Além disso, -printftem pouca relação com o printfutilitário de shell C ou POSIX printf. Usar esse nome histórico de função para algo diferente é muito pouco considerado. Os caras conservadores do BSD provavelmente o veem da mesma maneira, então provavelmente não veremos clones -printfno BSD, com esse nome.
Kaz
Eu discordo que é pouco considerado usar um nome de função familiar para executar uma tarefa semelhante em um contexto diferente. Por que o BSD provavelmente nunca apoiará isso é outra questão.
Ярослав Рахматуллин
2

Existe uma maneira melhor de remover tudo, exceto a última parte de um caminho de arquivo; com awk. É melhor porque o awk não é executado uma vez para cada arquivo. Em alguns casos, isso importa.

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

Procuramos apenas arquivos em ~ / tmp e obtemos uma lista em que cada entrada é separada por barras. Portanto, usamos uma barra como separador de campos (-F /) e imprimimos o parâmetro de campo ($ 1 .. $ 9) que corresponde ao último campo ($ NF).

Ярослав Рахматуллин
fonte
Este é o mais rápido que testei.
Paulo Almeida
Eu tenho usado o Cygwin ultimamente, e a criação de um processo no Windows é super caro ...
Ярослав Рахматуллин
2

EDIT :

Usando sed:

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

Usando o comando xargs , conforme mencionado na resposta de @nerdwaller

$ find . -type f -print0 | xargs --null -n1 basename
stderr
fonte
1
Obrigado por apontar isso, +1, eu não usei muito xargs ... Definitivamente deveria, já que você retirou alguns caracteres do meu comando.
Nerdwaller 16/07/2013
Este quebra quando os arquivos têm espaços. Funciona assim, pelo menos em um teste rápido:find . -type f -print0| xargs --null -n1 basename
Paulo Almeida
Nenhum dos dois --nullou -n1opções é acessível em OSX
Valeriy Van
1

Que tal isso:

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

Vantagem: Apenas exatamente um processo adicional é gerado, não um para cada resultado.

David Foerster
fonte
0

Você pode ligar sh de dentro da -execopção de localização e evitar o uso de tubos desnecessários. Isso também tem a vantagem de você não precisar se preocupar com nomes de arquivos engraçados (espaços, novas linhas etc.):

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