O que você está pedindo não faz muito sentido no caso geral, então não é surpresa que find
não tenha provisão para isso.
Um symlink com um alvo relativo é relativo ao caminho do symlink. Então, por exemplo, se percorrendo um diretório seguindo os links simbólicos, find
encontra a/b/c/d
e a
, a/b
, a/b/c
são todos links simbólicos relativos ou absolutos (ou links simbólicos para caminhos com componentes symlink), o que deveria faz?
Se você estiver procurando por uma diretiva find
ou uma diretiva -printf
%
do GNU que se expande para um caminho livre de links simbólicos para o arquivo relativo ao diretório atual ou a qualquer diretório Receio que não exista nenhum.
Se você estiver no Linux, poderá obter o caminho absoluto desses arquivos com:
find -L foo -type f -exec readlink -f {} \;
Como você descobriu, existe pelo menos um comando realpath
que aceita mais de um argumento de caminho que, em combinação com a sintaxe -exec cmd {} +
padrão, será muito mais eficiente, pois está executando como poucos comandos do caminho real como necessário:
find -L foo -type f -exec realpath {} +
find -L foo -type f -print0 | xargs -r0 realpath
pode ser mais rápido, como se fosse necessário mais de um comando realpath
, find
pode continuar procurando mais arquivos enquanto o primeiro realpath
começa a funcionar, o que mesmo em um sistema de processador pode torná-lo mais eficiente. / p>
-print0
e xargs -r0
não são padrão, vêm do GNU, mas são encontrados em várias outras implementações, como a maioria dos BSDs modernos.
O Zsh tem suporte embutido para ele:
print -rl foo/***/*(-.:A)
Se você não se importa com a ordem de classificação, pode desativar a classificação e torná-la um pouco mais eficiente com:
print -rl foo/***/*(-.oN:A)
Se você quiser convertê-los em caminhos relativos para o diretório atual, consulte a essa pergunta SO .
Se você sabe que todos esses arquivos têm um caminho canônico absoluto (cujo nenhum dos componentes são links simbólicos) dentro do diretório atual, você pode simplificá-lo para (ainda com zsh
):
files=(foo/***/*(-.:A))
print -rl -- ${files#$PWD/}
Apesar de ser curto e conveniente, e funciona como qualquer outro nome de arquivo, duvido que seja mais rápido que find
+ realpath
.
Com as ferramentas Debian realpath
e GNU, você pode fazer:
cd -P .
find -L foo -type f -exec realpath -z {} + |
gawk -v p="$PWD" -v l="${#PWD}" -v RS='find -L foo -type f -print0 |
xargs -r0 realpath -z --relative-base . |
xargs -r0 whatever you want to do with them
' -vORS='find -L foo -type f -exec readlink -f {} \;
' '
substr($0, 1, l+1) == p "/" {$0 = substr($0, l+2)}; 1' |
xargs -r0 whatever you want to do with them
Como percebo agora, agora há um realpath
nas versões recentes do GNU coreutils, que tem o recurso exato que você está procurando, então é só uma questão de
find -L foo -type f -exec realpath {} +
find -L foo -type f -print0 | xargs -r0 realpath
(use --relative-to .
em vez de --relative-base .
se você quiser caminhos relativos mesmo para arquivos cujo caminho livre do symlink não resida abaixo do diretório de trabalho atual).