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
rename
Se você tiver o utilitário 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 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 -n
quando estiver pronto para aplicar suas alterações ou altere-o para -v
para 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 azmv
funçã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 find
reunir a lista de arquivos para renomear. Não importa se rename
sã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 mv
para 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.