Script Bash para corrigir nomes de arquivos

Script Bash para corrigir nomes de arquivos

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 que tudo seja 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 preciso de um script bash regex recursivo ou algo semelhante para percorrer esses arquivos e renomeá-los.

Responder1

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

Seu requisito pede 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}. Presumo que você queira incluir os dois primeiros casos.

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

Remova o -nquando estiver pronto para aplicar suas alterações ou altere-o para -vpara ver o processamento dos arquivos conforme avança.

Responder2

A ferramenta mais fácil aqui seriazsh(como o bash, só que melhor), com seuglobulação chiquee azmvfunção. Execute-o no diretório de nível superior onde deseja renomear os arquivos.

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

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


Alternativamente, 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 para findreunir a lista de arquivos para renomear. Não importa se renamesão passados ​​arquivos não correspondentes, ele irá pular arquivos para os quais não há necessidade de renomear.

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

Responder3

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 diretório é o diretório principal onde estão todos os subdiretórios....

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

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

Responder4

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

1) Escreva um script que faça o que você desejaumnome do arquivo. Algo assim pode fazer:

#! /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 algumas vezes e use mvpara restaurar os nomes.

2) Invoque seu script comencontrar:

$ find dirname -exec script.awk {} +

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

informação relacionada