Estou usando o find para todos os arquivos no diretório, para obter uma lista de caminhos. No entanto, eu preciso apenas de nomes de arquivos. ou seja, eu recebo ./dir1/dir2/file.txt
e quero obterfile.txt
266
No GNU find
você pode usar -printf
parâmetros para isso, por exemplo:
find /dir1 -type f -printf "%f\n"
-o
tem precedência menor do que implícita-a
, por isso muitas vezes você vai querer agrupar seus-o
argumentos)Se a sua localização não tiver a opção -printf, você também poderá usar o nome da base:
fonte
... {} ';'
Use o
-execdir
que mantém automaticamente o arquivo atual{}
, por exemplo:Você também pode usar em
$PWD
vez de.
(em alguns sistemas, isso não produzirá um ponto extra na frente).Se você ainda tiver um ponto extra, alternativamente, poderá executar:
Quando usado em
+
vez de;
,{}
é substituído por tantos nomes de caminho quanto possível para cada chamada de utilitário. Em outras palavras, ele imprimirá todos os nomes de arquivos em uma linha.fonte
./filename
vez defilename
. Dependendo das suas necessidades, pode ou não estar bem.$PWD
vez de.
.Se você estiver usando o GNU find
Ou você pode usar uma linguagem de programação como Ruby (1.9+)
Se você gosta de uma solução bash (pelo menos 4)
fonte
Se você deseja executar alguma ação somente contra o nome do arquivo,
basename
pode ser difícil usá- lo.Por exemplo, isto:
apenas ecoará o nome da base
/my/found/path
. Não é o que queremos se queremos executar o nome do arquivo.Mas você pode então
xargs
a saída. por exemplo, para matar os arquivos em um diretório com base nos nomes em outro diretório:fonte
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \;
No mac (BSD
find
), use:fonte
-exec
e-execdir
são lentos,xargs
é rei.xargs
O paralelismo de também ajuda.Curiosamente, não posso explicar o último caso de
xargs
sem-n1
. Dá o resultado correto e é o mais rápido¯\_(ツ)_/¯
(
basename
pega apenas um argumento de caminho, masxargs
envia todos eles (na verdade, 5000) sem-n1
. não funciona no linux e no openbsd, apenas no macOS ...)Alguns números maiores de um sistema Linux para ver como
-execdir
ajuda, mas ainda muito mais lento que um paraleloxargs
:fonte
find
, é-execdir
que se torna o mais rápido, pois a criação de novos processos é uma operação relativamente cara.Honesta
basename
edirname
soluções são mais fáceis, mas você também pode verificar isso:ou
ou
fonte
Como outros já apontaram, você pode combinar
find
ebasename
, mas, por padrão, obasename
programa funcionará apenas em um caminho de cada vez; portanto, o executável precisará ser iniciado uma vez para cada caminho (usando umfind ... -exec
ou outrofind ... | xargs -n 1
), o que pode ser lento.Se você usar a
-a
opçãobasename
, ela poderá aceitar vários nomes de arquivos em uma única invocação, o que significa que você poderá usarxargs
sem o-n 1
para agrupar os caminhos em um número muito menor de invocaçõesbasename
, o que deve ser mais eficiente.Exemplo:
Aqui eu incluí o
-print0
e-0
(que deve ser usado em conjunto), a fim de lidar com qualquer espaço em branco dentro os nomes de arquivos e diretórios.Aqui está uma comparação de tempo, entre as versões
xargs basename -a
exargs -n1 basename
. (Para uma comparação do tipo com o mesmo, os tempos relatados aqui são após uma execução fictícia inicial, para que sejam feitos após os metadados do arquivo já terem sido copiados no cache de E / S.) Canalizei a saída paracksum
nos dois casos, apenas para demonstrar que a saída é independente do método usado.Como você pode ver, é realmente muito mais rápido evitar o lançamento
basename
todas as vezes.fonte
basename
aceitará vários nomes de arquivos sem precisar de argumentos adicionais na linha de comando. O uso-a
aqui é no Linux. (basename --version
me dizbasename (GNU coreutils) 8.28
.)Encontrei uma solução (na página makandracards), que fornece apenas o nome de arquivo mais recente:
(obrigado a Arne Hartherz)
Eu usei para
cp
:fonte