Mover arquivos de acordo com a correspondência de padrões

2

Eu tenho alguns arquivos cujo nome é assim:

XXXXX_S1_X_XX_X.txt
XXXXX_S2_X_XX_X.txt
XXXXX_S3_X_XX_XXX.txt
S4_X_XX_X.txt
XXXXX_S5_XX_X.txt   
...

Eu criei uma lista de pastas com o nome: S1 , S2 , S3 , .... Gostaria de mover o arquivo XXXXX_S1_X_XX_X.txt na pasta S1 , o arquivo XXXXX_S2_X_XX_X.txt in a pasta S2 e assim por diante. Eu escrevi esse loop simples, mas não sei copiar / mover arquivos de acordo com o padrão correspondente a S * na pasta correspondente:

for i in My_list_of_folders.txt
do 
  dir=${i%.txt}
  mkdir "$dir"
  cp "$i" "$dir"
done
    
por Elb 15.07.2018 / 17:51

2 respostas

3

Um loop ligeiramente modificado:

for pattern in S1 S2 S3 S4; do
   mkdir -p ./"$pattern"
   for filename in ./*"$pattern"*; do
       [ ! -f "$filename" ] && continue
       mv -i "$filename" "$pattern"/
   done
done

Isso percorre as strings de padrão S1 , S2 , S3 e S4 . O loop interno usa a string de padrão atual para procurar nomes no diretório atual que contém a sequência de caracteres em qualquer lugar. Ele ignora arquivos não regulares (como os próprios diretórios S1 , S2 etc.) e move todo o restante que corresponde ao diretório apropriado para essa sequência padrão.

Como o slm aponta nos comentários (agora excluídos), as operações no loop interno podem, nesse caso, ser bem encurtadas em apenas

[ ! -f "$filename" ] || mv -i "$filename" "$pattern"/

ou

[ -f "$filename" ] && mv -i "$filename" "$pattern"/

Se você tiver padrões sobrepostos, como S1 e S11 , será necessário fazer os padrões mais longos primeiro.

    
por 15.07.2018 / 18:14
2

Como alternativa:

for i in S{4..1};do 
  mkdir -p $i
  while read line; do 
    [ -f "$line" ] && mv "$line" $i
  done < My_list_of_folders.txt
done

Como funciona:

  • S{4..1} - usa a expansão de shell para construir os nomes de dirs
  • mkdir -p $i - força a criação do diretório
  • while read ... < My_list_of_folders.txt - percorre as linhas no arquivo
  • [ -f "$line" ]... - move cada arquivo para o diretório S correspondente

OBSERVAÇÃO: Você pode ajustar o glob ({4..1}) para qualquer faixa de suítes do seu caso de uso. Para lidar com algo maior, estamos ordenando coisas ao contrário para lidar com qualquer sobreposição S20 .... S1, daí o tipo S{20..1} de definição de nosso glob.

    
por 15.07.2018 / 18:28