Script Bash para corrigir nomes de arquivos

1

Eu tenho centenas de pastas com milhares de subdiretórios e arquivos dentro delas. Os nomes dos arquivos estão atualmente no formato

sf{number}-{number} - {text}

e preciso de tudo excluído até {text}.

Exemplo:

sf012-05 - toto - africa.cdg 
sf012-05 - toto - africa.mp3

- >

toto - africa.cdg
toto - africa.mp3

Formatos adicionais:

SF-108 - 02 Johnny Hates Jazz Shattered Dreams[K].cdg
02 - David Essex - Rock On.cdg
SF0504 - 13 Walker Brothers, The  Make It Easy On Yourself.cdg
SFLY 051 - 07 America  A Horse With No Name.cdg
SF217-12 this love - maroon 5.cdg
SF262-13. Same Mistake - James Blunt.cdg
SF287 - 13 Luke Bryan Do I.cdg
SF355-01-15 - Tough Love - Pony.cdg
Track 11 Livin' La Vida Loca (Radio Edit) - Martin, Ricky.cdg
Sunfly Hits 275 - 07 SF275-7-Right Now (Na Na Na)-Akon.mp3
Second, Minute Or Hour - Jack Penate.mp3
SF057 - Karaoke Classics Vol.57 - 03 Abba Thank You For The Music.cdg

especialmente o último é uma porcaria total.

Isso significa que eu preciso de um script recursivo regex bash ou algo semelhante para passar por esses arquivos e renomeá-los.

    
por Pulz 20.05.2016 / 19:08

4 respostas

0

A ferramenta mais fácil aqui seria zsh (como o bash, só que melhor), com seu fancy globbing e o zmv function . Execute isso no diretório de nível superior onde deseja renomear arquivos.

autoload -U zmv
zmv '(**/)[Ss][Ff][0-9]##-[0-9]##[- ]#(*)' '$1$2'

Explicação: **/ é qualquer sequência de diretórios principais. Em seguida, há um padrão de sf (insensível a maiúsculas e minúsculas) seguido por um ou mais dígitos, um traço e outro número, seguidos por traços e espaços. Finalmente, pode haver qualquer sufixo * . Os números na substituição referem-se aos grupos entre parênteses no padrão.

Como alternativa, você pode usar prename (o script de renomeação baseado em Perl, disponível no Debian e Arch Linux, pode precisar ser instalado separadamente em outras distribuições). Você precisará combiná-lo com find para reunir a lista de arquivos para renomear. Não importa se rename é passado em arquivos não correspondentes, ele ignorará arquivos para os quais não há renomeação a ser feita.

find -name '[Ss][Ff]*' -exec prename 's!/!sf[0-9]+-[0-9]+[- ]*!!i' {} +
    
por 21.05.2016 / 01:06
0

Aqui está o código (substitua o diretório pelo diretório principal ou onde você tem os subdiretórios):

cd directory
find -type f | while IFS= read - file; do 
    name=$(echo "$file"  | rev | cut -d'/' -f1 | rev |  cut -d'-' -f3- | cut -d' ' -f2-) 
    path=$(dirname "$file")  
    newname="${path}/${name}"
    echo mv "$file" "$newname" 
done

Onde directory é o diretório principal onde todos os subdiretórios são ....

Por favor, não remova o "echo" de "mv", teste primeiro.

Tenha cuidado para não executar isso no diretório errado, isso pode ser muito perigoso.

    
por 20.05.2016 / 19:28
0

Você diz que precisa de tudo excluído até {text} , mas seu exemplo não mostra isso. Em vez de mostrar o código exato, deixe-me sugerir um plano.

1) Escreva um script que faça o que você deseja para um nome do arquivo. Algo como isso pode acontecer:

#! /bin/sh
test -d ~/OK/${PWD} || mkdir -p ~/OK/${PWD}
ln "$1" "~/OK/${PWD}/$1"
echo "$1" | awk -F ' - ' '{print $NF}'

Isso quebra o nome no padrão '-' e imprime o último campo. E salva o nome do arquivo original para que você possa recuperá-lo se algo der errado. Teste-o algumas vezes e use mv para restaurar os nomes.

2) Invoque seu script com find :

$ find dirname -exec script.awk {} +

Isso enterrará sua máquina com muitas invocações paralelas do seu script. Quando estiver pronto, você terá um monte de diretórios OK para remover, e você saberá como usar o find para removê-los.

    
por 25.05.2016 / 03:50
0

Se você tiver o utilitário rename baseado em Perl (chamado prename em algumas distribuições), poderá usar uma expressão regular para renomear todos os arquivos de uma só vez.

Seu requisito solicita a remoção de sf{number}-{number} , mas todos os exemplos começam com maiúsculas, alguns deles contêm apenas um {number} , {number}-{number}-{number} ou mesmo {number}{space}-{space}{number} . Suponho que você queira incluir os dois primeiros casos.

rename -n 's/^sf[0-9-]+\s+(-\s+)?//' [Ss][Ff]*

Remova o -n quando estiver pronto para aplicar as alterações ou altere-o para -v para ver os arquivos processados.

    
por 25.05.2016 / 10:44

Tags