Adicionar a um prefixo nome do arquivo o nome do seu diretório

0

Eu tenho cerca de 100 diretórios, como:

  • andando,
  • escrevendo,
  • dançando,
  • nadando.

Cada um desses diretórios contém um conjunto de arquivos.

l gostaria de adicionar o nome do prefixo do diretório aos nomes de arquivos de seus arquivos.

Por exemplo:

writing :
0ZPQl5QUvo0_000202_000212.mp4  
AFV8x8ezN8g_000016_000026.mp4  
-HutuMqTAPw_000275_000285.mp4 
qtvsw6h3yQo_000228_000238.mp4  
Ub0rc6U6nfI_000100_000110.mp4

torna-se:

writing :
writing_0ZPQl5QUvo0_000202_000212.mp4  
writing_AFV8x8ezN8g_000016_000026.mp4  
writing_-HutuMqTAPw_000275_000285.mp4 
writing_qtvsw6h3yQo_000228_000238.mp4  
writing_Ub0rc6U6nfI_000100_000110.mp4

Como posso fazer isso?

    
por Joseph 23.01.2018 / 13:59

4 respostas

3

Aqui está uma versão ligeiramente melhorada do seu script - as principais diferenças são

  • usando um shell glob * no lugar de $(ls) - consulte Armadilha de Bash # 1

  • citando qualquer expansão de variável (permite nomes de arquivos com espaço em branco ou outros caracteres engraçados - veja Bash Pitfall # 2 )

  • marcando o final das opções para mv usando a extensão -- GNU - isso permite manipular nomes de arquivos que começam com hífens, bem

Então

for d in *; do 
  [[ -d "$d" ]] && cd "$d" || continue
  for f in *.mp4; do 
    echo mv -v -- "${f}" "${d}_${f}"
  done
  cd -
done

Ou, de forma mais portável, você pode fazer um loop de ./*.mp4 para proteger dos hífenes principais - mas, em seguida, você precisa retirá-lo durante o mv

for d in *; do 
  [ -d "$d" ] && cd "$d" || continue
  for f in ./*.mp4; do 
    echo mv -v "${f}" "${d}_${f#./}"
  done
  cd -
done

Em ambos os casos, remova o echo (e o -v , se desejar), assim que tiver certeza de que está funcionando como você espera.

    
por steeldriver 23.01.2018 / 16:09
1

O problema é resolvido usando o seguinte script:

for i in $(ls); do                                                 
  if [ -d $i ]; then                      
     fname=${i##*/}                 
     echo $fname                           
     cd $i                                       
     for z in *.mp4; do               
       echo $z  
       cp $z ${fname}_${z}
       rm $z                   
     done                                        
     cd ..                                         
  fi                                              
done
    
por Joseph 23.01.2018 / 14:24
0

Supondo que você esteja no diretório que contém todos esses diretórios dancing , writing , etc, o comando

for folder in $(find -mindepth 1 -type d); do
  cd $folder
  PRE=${folder#./}
  for file in *; do
    mv "$file" "${PRE}_$file"
  done
  cd ..
done

vai conseguir o que você quer. Eu testei e funcionou mesmo quando os nomes de arquivos continham espaços ou novas linhas. Não funcionou com esses caracteres nos nomes das pastas, por exemplo walking slowly .

Editar: O código anterior não manipula espaços ou novas linhas em nomes de pastas. Para cobrir isso, use o código modificado

for folder in *; do
  if [ -d "$folder" ]; then
    cd "$folder"
    PRE=${folder#./}
    for file in *; do
      mv "$file" "${PRE}_$file"
    done
    cd ..
  fi
done

Editar 2: Se um nome de arquivo começar com - (traço), o comando poderá interpretá-lo como uma opção. Para lidar com os traços principais, insira um -- entre o comando mv e seus argumentos. Isso diz ao mv para parar a verificação de opções.

Então o código final é

for folder in *; do
  if [ -d "$folder" ]; then
    cd "$folder"
    for file in *; do
      mv -- "$file" "${folder}_$file"
    done
    cd ..
  fi
done
    
por Stefan Hamcke 23.01.2018 / 14:29
0

Use find e prename :

find DIR... -mindepth 1 -type f | prename -n 's/([^\/]+)\/([^\/]+)$/$1\/$1_$2/'

Remova a opção -n para realmente renomear os arquivos e não apenas para imprimir como os arquivos seriam renomeados.

    
por David Foerster 23.01.2018 / 19:53