Em primeiro lugar, você não precisa escanear os 10TB completos, apenas a estrutura de diretórios, então fazer a busca básica não é tão ruim quanto parece.
Segundo, se você fizer o básico e começar todos os dez ao mesmo tempo, provavelmente obterá melhor desempenho por causa do cache de leitura.
Ou você pode fazer find /home -uid 812 -o uid 813 -o
... -printf '%U:%p%code%'| sed -zre 's!["$]!\&!g' -e 's/^812:(.*)$/chown NEWUSER1 ""/'e -e 's/^813
...
Acho que descobri as principais armadilhas, mas o teste é sempre arriscado. Se você não estiver usando o GNU sed, você pode enviar a saída para um shell.
Aqui está uma versão mais limpa com melhor manipulação de cotações usando as ferramentas do gnu.
find /home -uid 812 -o uid 813 -o ' ... ' -printf '%U:' -print0| \
sed -zre "s/'/'\''/g" \
-e 's/^812:(.*)$/chown NEWUSER1 '"''/e" \
-e 's/^813:(.*)$/chown NEWUSER2 '"''/e" \
...
A maneira como eles funcionam:
A primeira parte do achado é um monte de verificações uid ORed, a carne é o printf (ou printf e print0 na segunda versão) que imprime o uid numérico, dois pontos, o nome do arquivo com c escapa (sem escapes na segunda versão) e um nulo para cada arquivo. Então sed usando o separador nulo e regex estendido cita cifrões e aspas duplas, em seguida, com uma expressão por usuário corresponde a uid e dois pontos separa o nome do arquivo cria uma linha de comando shell para fazer um chown e avalia-o com um shell. Eu provavelmente deveria ter passado alguns minutos a mais verificando a lista de escapes no printf, mas o suficiente para começar se você testar sem o flag e no comando s. Na segunda versão, o único caractere que escapou é a aspa simples. A razão para não escapar é permitir que todos os caracteres, exceto null, passem sem um significado especial após o cabeçalho estritamente definido, não precisamos remover os escapes.