Renomeando uma lista de arquivos de um arquivo de texto

0

Eu tenho uma pasta contendo essa lista de arquivos.

lesson1.mp4
lesson2.mp4
lesson3.mp4
lesson4.mp4

Estou tentando renomear esses arquivos com base no conteúdo de "rename.txt"

 1. Introduction to the React Ecosystem Video 
 2. Video Babel, Webpack, and React 
 3. Solution - Props 
 4. Solution - .map and .filter 

Estou executando este script

for file in *.mp4; 
do read line;  
mv -v "${file}" "${line}";  
done < rename.txt

que me dá resultados indesejados

'lesson1.mp4' -> '1. Introduction to the React Ecosystem Video '
'lesson10.mp4' -> '2. Video Babel, Webpack, and React '
'lesson11.mp4' -> '3. Solution - Props '
'lesson12.mp4' -> '4. Solution - .map and .filter '
'lesson13.mp4' -> '5. Video Validating Components with PropTypes'

Resultados desejados.

'lesson1.mp4' -> '1. Introduction to the React Ecosystem Video.mp4'
'lesson2.mp4' -> '2. Video Babel, Webpack, and React.mp4'
'lesson3.mp4' -> '3. Solution - Props.mp4'
'lesson4.mp4' -> '4. Solution - .map and .filter.mp4'
'lesson5.mp4' -> '5. Video Validating Components with PropTypes.mp4'
    
por Prãtéék Thápá 21.02.2018 / 11:02

2 respostas

0

Você poderia usar a expansão de shell em vez de globbing:

for file in lesson{1..10}.mp4;do
       read line
       mv -v "${file}" "${line}"
done < rename.txt

Embora isso pareça bastante propenso a erros, se você tiver muitos arquivos, precisará compará-los com o número no início da linha do arquivo renomeado. Algo como:

for file in *.mp4;do
       num=$(echo "${file}" | sed -E 's/^lesson([0-9]+).mp4$//')
       line=$(grep -E "^ *${num}\." rename.txt)
       mv -v "${file}" "${line}"
done

Desta forma, não importa qual a ordem em que o arquivo rename.txt está, e não importa qual ordem o shell coloca nos nomes dos arquivos.

    
por 21.02.2018 / 12:22
0

Essa resposta usa a opção -v de ls para garantir a classificação numérica adequada da lista de arquivos. Cada nome de arquivo é colocado em um parâmetro posicional de shell. Para garantir que um nome de arquivo completo seja colocado em cada parâmetro, ele temporariamente altera o 'separador de campo interno' do shell para que, se você acabar tendo nomes de arquivo com espaços incorporados, ele ainda funcione. Finalmente, como detesto nomes de arquivos com espaços incorporados (e você faria bem em desenvolver um instinto semelhante), ele converte todos os espaços incorporados em sublinhados. O comando shift simplesmente ativa os valores de todos os parâmetros posicionais, então $1 obtém o próximo valor na lista.

oldifs="${IFS}"
IFS=$'\n'
set $(ls -v1 lesson*)
while read line ; do
  mv "$1" "${line// /_}"
  shift
done < rename.txt
IFS="${oldifs}"
    
por 21.02.2018 / 15:54