Geralmente você deseja usar find -exec
para executar um comando para todos os nomes de arquivos ou find -print0
para enviar os nomes para algum comando que possa ler entradas separadas por nul bytes (como xargs -0
).
Se você realmente deseja ter strings entre aspas, o Bash tem algumas opções para fazer isso:
$ find -exec bash -c 'printf "%s\n" "${@@Q}"' sh {} +
'./single'\''quote'
'./space 1'
$'./new\nline'
'./double"quote'
$ find -exec bash -c 'printf "%q\n" "$@"' sh {} +
./single\'quote
./space\ 1
$'./new\nline'
./double\"quote
Isso requer uma invocação extra do shell, mas lida com vários nomes de arquivos com um exec.
Em relação a salvar os bits de permissão (embora não o ACL), você poderia fazer algo assim (no GNU find):
find -printf "%#m:%pperl -0 -ne '($m, $f) = split/:/, $_, 2; chmod oct($m), $f; ' < files-and-modes
" > files-and-modes
Isso produziria entradas com as permissões, dois-pontos, o nome do arquivo e um byte nulo, como: 0644:name with spaces
. Ele não escapará de nada, mas imprimirá os nomes dos arquivos como estão (a menos que a saída vá para um terminal, caso em que pelo menos novas linhas serão desconfiguradas.) IFS=" "
Você pode ler o resultado com um script Perl:
while IFS=: read -r -d '' mode file ; do
# do something useful
printf "<%s> <%s>\n" "$mode" "$file"
chmod "$mode" "$file"
done < files-and-modes
Ou mal no Bash, veja os comentários:
$ find -exec bash -c 'printf "%s\n" "${@@Q}"' sh {} +
'./single'\''quote'
'./space 1'
$'./new\nline'
'./double"quote'
$ find -exec bash -c 'printf "%q\n" "$@"' sh {} +
./single\'quote
./space\ 1
$'./new\nline'
./double\"quote
Tanto quanto eu testei, isso funciona com novas linhas, citações, espaços e dois-pontos . Note que precisamos usar algo diferente de espaço em branco como separador, já que a configuração %code% removeria espaços à direita se algum nome os contiver.