Eu tenho uma estrutura de arquivos assim:
- 00000010
- 000000001.arquivo1
- 000000001.arquivo2
- 00000020
- 00000003.arquivo1
- 00000003.arquivo2
- 00000003.arquivo3
- ...
Portanto, existem pastas com nomes de 8 dígitos contendo um ou mais arquivos com nomes começando com números de 8 dígitos. Mas esses nomes de arquivos estão – digamos – fora de sincronia. Então agora tento renomeá-los recursivamente no bash para arquivar:
- 00000010
- 000000010.arquivo1
- 000000010.arquivo2
- 00000020
- 00000020.arquivo1
- 00000020.arquivo2
- 00000020.arquivo3
- ...
Meu script se parece com:
#! /bin/bash
find * -maxdepth 1 -name "*" -type d | while read -r dir
do
rename 's/$dir\/[0-9]{8}/$dir/' *
done
Mas isso não está funcionando e dá erros como
O símbolo global "$dir" requer um nome de pacote explícito na (eval 1) linha 1.
Como eu poderia escrever para renomear os arquivos de acordo com os nomes das pastas?
Obrigado pela ajuda!
Responder1
Como aprendi em outra resposta, que tenho que usar
rename "s/$dir\/[0-9]{8}/$dir\/$dir/" $dir/*
Caso alguém tenha o mesmo problema...
Responder2
Eu realmente não gosto da resposta onde $dir
está interpolado no padrão. Isso poderia levar a resultados inesperados se o diretório contivesse, por exemplo, um caractere que fosse interpretado como um token regexp especial.
Prefiro combinar os arquivos diretamente no padrão, eliminando a necessidade de fazer um loop nos diretórios e usar apenas um glob normal.
rename 's#([^/]+)/[^/]+(\.file[0-9]+)$#$1/$1$2#' base_directory/*/*
onde o glob atinge os arquivos individuais dentro dos diretórios (pode até ser especificado como base_directory/*/*.file*
, ou similar, mas isso não deve importar aqui).
Observe que este é o comando completo, sem necessidade de find
construção.
- Eu uso
#
como separador em vez do "normal"/
para evitar ter que escapar disso nos padrões. - Eu capturo o grupo (ganancioso) de "não é um separador de diretório", seguido por um separador de diretório, seguido por um nome de arquivo e um final de linha. Isso faz com que o primeiro grupo de captura seja o diretório pai de cada arquivo.
- A primeira parte do nome do arquivo é descartada, exceto a finalização para manter o sufixo ordinal.
Optei por usar uma abordagem mais geral do que presumir que os arquivos tinham 8 caracteres, mas a verdadeira diferença é que não preciso da find
construção nem de amontoar a $dir
variável no ambiente regexp (possivelmente inseguro).