Eu assumo que os nomes dos arquivos não contêm novas linhas ou espaços em branco inicial ou final (o formato SFV não suporta esses de qualquer forma) e que você tem utilitários GNU (Linux não integrado, Cygwin).
Primeiro, gere um mapeamento de nomes de arquivos para números de inodes e classifique-os por números de inode.
tmpdir=$(mktemp -d)
find .* * -xdev -name .. -prune -o -type f -printf '%i %p\n' |
sort -k 1n > "$tmpdir/inodes.txt"
Gere um arquivo de soma de verificação para o primeiro arquivo com cada número de inode.
<"$tmpdir/inodes.txt" awk '$1 != previous {previous = $1; sub(/^[0-9]+ /,""); print}' |
xargs cfv -C - >"$tmpdir/1.cfv"
Agora, conclua o arquivo de soma de verificação aproveitando os links físicos. Eu não sei se cfv
imprime os arquivos na ordem em que eles são passados na linha de comando, se isso acontecer você pode economizar memória nesta etapa porque o arquivo CFV temporário e o arquivo inode serão ordenados no mesma maneira.
awk '
FNR==1 {
match($0, / +[[:alnum:]] *$/);
cksums[substr($0, 1, RSTART-1)] = substr($0, RSTART);
next
}
{ inode = $1; sub(/^[0-9]+ /, ""); }
previous != inode { cksum = cksums[$0] }
{ print $0, cksum }
' "$tmpdir/1.cfv" "$tmpdir/inodes.txt" >full.cfv
Você pode então remover os arquivos temporários.
Aviso: código não testado.