Encontre arquivos, renomeie-os usando “uuidgen” e adicione extensão

3

Eu tenho uma lista de arquivos em uma determinada pasta sem extensão. Quero renomeá-los e adicionar uma extensão. O nome deve ser UUID. Eu sei como encontrá-los e há o utilitário "uuidgen" para gerar o UUID, como posso fazer o resto?

find . -type f -name 'file*' # ??? -exec .... ???
    
por Johshi 28.08.2016 / 08:18

1 resposta

5

Tente:

find . -type f -name 'file*' -execdir sh -c 'mv "$1" "$(uuidgen).ext"' Renamer {} \;

Como funciona

  • find . -type f -name 'file*' -execdir ... \;

    Esta parte com a qual você parece estar familiarizado: encontra arquivos cujos nomes correspondem ao glob file* e executa o comando ... neles, onde, no nosso caso, ... é substituído por:

  • sh -c 'mv "$1" "$(uuidgen).ext"' Renamer {}

    Isso inicia um shell, executa um comando mv e disponibiliza o nome do arquivo como $1 . ( Renamer é uma cadeia arbitrária que o shell atribui a $0 que o shell usaria se gerasse uma mensagem de erro.) O comando find substitui {} pelo nome do arquivo encontrado e é isso que o shell atribui a $1 . Vamos ver apenas o comando shell:

  • mv "$1" "$(uuidgen).ext"

    Isso renomeia o arquivo de $1 para um nome criado por uuidgen .

    Como o nome do arquivo pode conter espaços ou outros caracteres difíceis, colocamos $1 entre aspas duplas para proteger o nome da divisão de palavras ou das expansões de shell.

Usamos -execdir em vez de -exec por dois motivos:

  1. Torna o comando mv mais fácil: não é necessário código extra para garantir que o arquivo renomeado permaneça no mesmo diretório.

  2. -execdir é mais seguro: se um diretório foi renomeado enquanto o comando find estava em execução, -exec , mas não -execdir , pode falhar muito.

Por que iniciar um novo shell?

Pode ser tentador tentar usar:

find . -type f -name 'file*' -execdir mv {} "$(uuidgen).ext" \; # Don't do this

O problema aqui é que uuidgen seria executado apenas uma vez. O shell executaria uuidgen antes até mesmo iniciar o comando find . Como conseqüência, todos os comandos mv terão o nome do arquivo de destino mesmo . Queremos que uuidgen seja executado uma vez para todos os arquivos encontrados por find . É por isso que precisamos executar mv e uuidgen sob o comando sh .

Versão mais eficiente

O item acima inicia um novo shell para cada arquivo encontrado. A abordagem a seguir, por outro lado, pode processar muitos milhares de arquivos por processo de shell iniciado:

find . -type f -name 'fi*' -execdir sh -c 'for f; do mv "$f" "$(uuidgen).ext"; done' Renamer {} +
    
por 28.08.2016 / 08:27