Você pode fazer:
find . -type f -links +1 -exec sh -c '
{ rm -f "$1" && cat > "$1"; } < "$1"' sh {} \;
Mas isso não preservará os metadados do arquivo. No Linux, você pode fazer isso:
find . -type f -links +1 -exec sh -c '
{ rm -f "$1" && cp -p /proc/self/fd/0 "$1"; } < "$1"' sh {} \;
Observe que se cat
ou cp
falhar (como no disco cheio), você perderá o conteúdo do arquivo que cat
/ cp
não conseguiu copiar.
Usamos -exec {} \;
em vez de -exec {} +
para que a contagem de links do arquivo seja atualizada depois que o arquivo for encontrado, de forma que find
não encontre o último link se o link count caiu para 1 (o que significa que para um arquivo com contagem inicial de links de 4, apenas 3 instâncias serão sobrescritas).
Com o GNU tar
, você também pode fazer:
find . -type f -links +1 -print0 |
tar --hard-dereference --null -T - -cf - | tar xpf -
Isso executará menos comandos, mas sobrescreverá mais arquivos.
Você pode ver alguns:
tar: ./file: file changed as we read it
para arquivos grandes, mas tudo bem, já que o segundo tar
irá desvincular o arquivo antes de sobrescrevê-lo. Isso será muito semelhante à primeira abordagem. É apenas a primeira tar
a notar que a contagem de links está diminuindo (e a mudança da hora como resultado) quando o segundo tar desassocia o arquivo.