Como criar dinamicamente a estrutura do diretório de destino ao usar o mv com curingas no bash?

1

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.

    
por Manuel 12.02.2014 / 10:42

1 resposta

1

Isso criará apenas os diretórios ano / carta que são realmente usados em nomes de arquivos.

cd "$SOURCEDIR"
for f in 123456789012_[A-Z]?_??_[0-9][0-9][0-9][0-9]????.dat ; do
    letter=${f:13:1}
    year=${f:19:4}
    dest="$DESTBASEDIR/$year/$letter"
    mkdir -p "$dest"
    mv "$f" "$dest"
done

Observe que usar ${braces} não é o mesmo que usar "$quotes" se o valor da variável contiver espaço em branco

    
por 12.02.2014 / 12:44

Tags