find . -iname '*.zip' -exec bash -c 'name=$(unzip -qql "" '*_IPC.csv' | grep -oE '[[:digit:]]{8}_IPC.csv' | head -n1); [ "$name" ] && mv "" "${name%csv}zip"' none {} ';'
Como funciona
Este comando tem o formato:
find . -iname '*.zip' -exec bash -c '...' none {} ';'
Isso procura o arquivo .zip no diretório atual e todos os subdiretórios abaixo dele. Para cada arquivo encontrado, o comando bash entre aspas simples é executado. O nome do arquivo encontrado é fornecido no argumento um, , para o comando bash. No nosso caso, o comando bash tem duas partes. O primeiro extrai o nome do arquivo csv e o salva na variável bash
name
:
name=$(unzip -qql "" '*_IPC.csv' | grep -oE '[[:digit:]]{8}_IPC.csv' | head -n1)
O acima usa substituição de comando : o comando dentro de $(...)
é executado e sua saída padrão é capturada. Neste caso, atribuímos a variável name
. O comando unzip -qql "" '*_IPC.csv'
extrai silenciosamente todos os nomes de arquivo do arquivo zip que correspondem ao glob *_IPC.csv
. Nós não precisamos limitar ao glob *_IPC.csv
, mas, se o arquivo zip tiver muitos arquivos, isso pode acelerar as coisas.
O comando grep, rep -oE '[[:digit:]]{8}_IPC.csv'
seleciona apenas os nomes que começam com 8 dígitos. O comando head -n1
seleciona o primeiro nome encontrado. Se houvesse apenas um desses nomes, head -n1
não seria necessário. Mas, manter head
poderia acelerar as coisas, porque faz com que o pipeline termine após a primeira partida.
A segunda parte testa que obtivemos um name
não vazio e, em caso afirmativo, renomeia o arquivo zip:
[ "$name" ] && mv "" "${name%csv}zip"
O texto acima usa remoção de sufixo para alterar o nome do arquivo csv para um nome de arquivo zip. ${name%csv}
retorna $name
depois de ter removido o sufixo csv
. ${name%csv}zip
adiciona um sufixo de zip.