Sou bem novo no script BASH e estou procurando uma maneira elegante de resolver minha tarefa:
Em um determinado diretório, determinados arquivos precisam ser classificados em subpastas. O nome dos arquivos tem uma estrutura fixa e a pasta de destino em que esses arquivos serão colocados depende de seus nomes.
No momento, meus scripts são assim:
#!/bin/bash
declare -r SOURCEDIR=/some/dir/upload
declare -r DESTBASEDIR=/some/dir/archive
for year in "2009" "2010" "2011" "2012" "2013" "2014"; do
for letter in {0..9} {A..Z}; do
mkdir -p ${DESTBASEDIR}/${year}/${letter}
mv ${SOURCEDIR}/123456789012_${letter}?_??_${year}????.dat ${DESTBASEDIR}/${year}/${letter}/
done
done
O script faz exatamente o que eu quero, mas cria pastas de destino mesmo que o mv não encontre nenhum arquivo para ser movido para lá. Eu gostaria de um mv com uma opção para criar diretórios necessários em vez de criá-los usando o mkdir.
Eu sei que esse script exibirá erros quando não houver nenhum arquivo para mover. Vou suprimir as mensagens de erro, quando o script estiver completo.
Existe uma maneira fácil e elegante de criar a estrutura de diretórios rapidamente sem criar diretórios de itens?
Obrigado pela sua ajuda!
Atenciosamente
Manuel
A versão de glenn jackman inspirou-me nos seguintes scripts que fazem o seguinte:)
#!/bin/bash
declare -r SOURCEDIR=/some/dir/upload
declare -r DESTBASEDIR=/some/dir/archive
cd "$SOURCEDIR"
for f in 1234567890_* ; do
letter=${f:11:1}
year=${f:21:4}
dest="$DESTBASEDIR/$year/$letter"
mkdir -p "$dest"
mv "$f" "$dest"
done
Observe que os deslocamentos dentro do nome do arquivo foram movidos desde que descobri, o número inicial no início do nome do arquivo é menor. A solução dada foi projetada no meu falso exemplo.
Esta abordagem é menos segura, pois não verifica, se os nomes de arquivos dos arquivos no diretório de origem são compostos como supostos. Nesse caso, posso confiar nisso, então não arrisco muito não verificando isso.
A linha dada na versão de glenn jackman
for f in 123456789012_[A-Z]?_??_[0-9][0-9][0-9][0-9]????.dat ; do
não funcionou. O valor depois de "in" foi interpretado como uma string literal no meu bash. Eu não sei como 'consertar' isso.