Encontrar -exec dry run?

Dec 27 2020

Existe uma maneira de ver qual seria o resultado de a find . -exec somecommand {} \;com as substituições, sem realmente executar os comandos? Como uma simulação (ou teste ou impressão)?

Por exemplo, suponha que eu tenha a seguinte estrutura de arquivo:

/a/1.txt
/a/2.txt
/a/b/3.txt

Existe uma maneira de testar find . type f -exec rm {} \;de dentro do adiretório de forma que a saída seja impressa em stdout, mas não executada, como:

rm 1.txt
rm 2.txt
rm b/3.txt

Nota de atualização : rmé apenas um comando de exemplo, estou interessado no caso geral

Respostas

18 rAlen Dec 27 2020 at 07:10

Você pode correr em echo rmvez derm

find . type f -exec echo rm {} \;

Além disso, findtem a -deleteopção de excluir arquivos que encontrar

3 l0b0 Dec 27 2020 at 07:28

Para rmespecificamente, você não precisa -exec: basta executar find . -type fa lista e adicione -deletepara excluir os arquivos listados pelo comando anterior (obviamente, impedindo quaisquer arquivos correspondentes sendo criado / apagou nesse meio tempo).

Além disso, para comandos como rmque ter um número arbitrário de argumentos que você vai querer substituir \;com +para executar como alguns comandos possíveis.

2 CharlesDuffy Dec 28 2020 at 00:38

É um pouco complicado, mas ao contrário das abordagens que usam echo, o código de saída a seguir pode ser executado em seu shell sem nenhuma alteração para ter o resultado correto, mesmo quando os nomes de arquivo contêm aspas, espaços, metacaracteres de shell, etc.

printcmd() { printf '%q ' "$@"; printf '\n'; } find . -exec bash -c "$(declare -f printcmd); "'printcmd "$@"' _ \
  somecommand {} \;

Observe que a string que estamos acrescentando ao nosso -execargumento é precisamente bash -c "$(declare -f printcmd); "'printcmd "$@"' _- o se $(declare -f printcmd)expande para o código da função; depois disso, chamamos a função com argumentos $1e adiante, e colocamos _como um espaço reservado para $0.

Você pode substituir zshou em kshvez de bash, se quiser que a saída escape para esse shell.