remove todas as instâncias de _000 de vários arquivos

3

Tive que recuperar minha biblioteca de músicas de um HDD que morreu .... tenho tudo o que eu queria, mas todos os nomes de faixas de música têm _000 adicionados no final.

Eu realmente não gosto de percorrer 8000 faixas de música individuais e escolher renomear para remover a string _000

Como posso pesquisar toda a pasta Música que contém todos os subdiretórios do álbum e remover todas as ocorrências de _000 em todos os nomes de faixas individuais?

    
por Nick 11.04.2015 / 21:07

3 respostas

2

Embora a solução mikesrv seja muito melhor e mais segura, acho que isso pode ser feito também com renomear :

find Music/ -type f -name '*_000' -print0 | xargs -r0 rename -v '_000' ''

Mas ainda há possíveis problemas como mencionado, por exemplo, album_00020_000 será renomeado para album20 , o que obviamente não é o comportamento desejado.
Eu acho que na distribuição do Debian foi uma ferramenta perl renomear que poderia fazê-lo. Mas infelizmente não consigo encontrar uma maneira de instalá-lo. Então eu encontrei seguindo o script perl aqui que pode ser suficiente:

#!/usr/bin/perl -w
# rename - Larry's filename fixer
$op = shift or die "Usage: rename expr [files]\n";
chomp(@ARGV = <STDIN>) unless @ARGV;
for (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    rename($was,$_) unless $was eq $_;
}

Assim, você pode tornar esse script executável e executar:

find Music/ -type f -name '*_000' | /path_to_script/rename.pl 's/_000$//'
    
por 11.04.2015 / 22:14
2
cd Music/..    &&
mkdir Music2   &&
pax -'rwls|\([^/]\)_000$||p' Music Music2

Se executado a partir do diretório pai de Music , os comandos acima criarão um diretório chamado Music2 , em seguida, espelhará a estrutura de caminho Music em Music2 w / hardlinks, removendo qualquer ocorrência de _000 encontrado na cauda de qualquer nome de arquivo nele.

Em seguida, você terá basicamente duas rotas para o conteúdo de Music em Music/.. - uma em que alguns arquivos são nomeados com sequências _000 finais e um no qual há um menos _000 no cauda de cada nome de arquivo do que existe no outro (exceto para arquivos nomeados apenas _000 que não são alterados) - mas os arquivos reais são intocados. Se você achar que Music2/Music combina com você melhor - rm -rf Music e mv Music2/Music Music depois.

A suposição é que todo o conteúdo de Music está localizado no mesmo sistema de arquivos montado e que suporta hardlinks.

O perl-rename usado abaixo é o que pode ser encontrado em cpan.org em ~pederst/rename . Eu o instalei em um sistema Arch Linux com pacman . Agora, me disseram que há outro script mais seguro perl com o mesmo nome, que também pode ser encontrado em cpan.org/~rmbarker/File-Rename-0.20 . mas eu não tive sucesso em fazer isso funcionar. Esta falha é mais provável de fazer com o meu ser perl-inepto do que qualquer outra coisa embora.

De qualquer forma, aqui está um pequeno estudo de caso sobre os perigos de soluções de renomeação com script versus hardlinking com base em um padrão.

mkdir Music Music2
echo file1 >Music/file
echo file2 >Music/file_000
pax -'rwls|_000$||p' Music Music2

Eu uso o sinalizador p rint para a opção -s ubstitute para pax acima, então pax imprime somente os nomes dos arquivos que ele altera, embora vincule todos eles . Imprime:

Music/file_000 >> Music/file

Agora vamos ver como fizemos:

grep . /dev/null Music/* Music2/Music/*

OUTPUT

Music/file:file1
Music/file_000:file2
Music2/Music/file:file2

Uhoh. O resultado da vinculação de file de file_000 sobrescreveu a dentry para uma file anteriormente existente ao executar a operação de espelhamento. Mas neste caso, o link original ainda existe - e assim o arquivo também funciona. Além de manter uma cópia dentária de cópia no diretório existente do arquivo, pax (por padrão) -p reserva todos os atributos de arquivo que puder, independentemente dos arquivos que deve criar ou copiar, como deve crie diretórios (que não podem ser hardlinked) e se a fonte estiver em um sistema de arquivos diferente (que pode ser totalmente evitado com -X ) ele deve copiar.

E assim os dois diretórios diferentes podem ser comparados após o fato para diferenças antes de quaisquer alterações inalteráveis. E com o sinalizador p rint, você pode pegar os resultados que lhe entregam e fazer referência cruzada a todos os originais existentes. Se eles existirem, você terá pelo menos um arquivo tímido no novo destino.

Por outro lado, embora:

find Music -name \*_000 -exec perl-rename 's/_000$//' {} +
grep . /dev/null Music/*

OUTPUT

Music/file:file2

O mesmo não é verdadeiro quando o link do sistema de arquivos last para um arquivo é sobrescrito - esse arquivo é histórico.

    
por 11.04.2015 / 21:21
1

Use o comando find para enumerar arquivos em um diretório e seus subdiretórios recursivamente. Existem várias maneiras de renomear arquivos. Você pode usar o comando rename do Linux:

find Music -depth -name '*_000' -exec rename _000 '' {} \;

Isso remove a primeira ocorrência de _000 em cada nome de arquivo. Tenha em atenção que, se tiver ficheiros cujo nome contenha _000 no meio, isso não lhe dará o nome desejado.

No Debian e nos seus derivados (Ubuntu, Mint,…), o comando rename é diferente; o Linux é chamado de rename.ul e o rename pode ser usado dessa maneira (que sempre remove o _000 no final, mesmo que haja um no meio):

find Music -depth -name '*_000' -exec rename 's/_000$//' {} +

Uma maneira mais fácil de renomear esses arquivos é instalar o zsh (disponível na maioria das distribuições) e usar o zmv function. Execute autoload -U zmv (ou coloque em ~/.zshrc ) e então

zmv 'Music/**/*_000' '${f%_000}'
    
por 12.04.2015 / 02:42