Recentemente, converti todos os meus arquivos FLAC para uma taxa de amostragem menor de 44,1 kHz e profundidade de bits de 24 bits (porque o iPhone / iPod não suporta nada acima disso) usando XLD no meu Mac OS 10.7 (Lion).
Embora eu tenha dito ao XLD para substituir todos os arquivos anteriores, o XLD anexou um (1)
no final do mesmo arquivo, como de
some_song.m4a
para
some_song(1).m4a
Então agora eu quero remover isso (1)
de todos os arquivos FLAC que converti.
Sei que provavelmente poderia ter usado algum programa ou mesmo um AppleScript para renomear os arquivos, mas queria aprender usando a maneira antiga de linha de comando.
Eu sei que find . -name *\(1\).m4a
vai pegar todo o arquivo FLAC convertido.
Em seguida, sei que tenho que fazer algo com -exec
e mv
renomear todos os arquivos encontrados. Mas o que não consigo descobrir é como manter o nome do arquivo original e apenas remover o arquivo (1)
.
Talvez eu precise fazer alguma captura de regex de grupo para armazenar a parte do nome do arquivo que não quero modificar? Ou talvez não seja possível fazer tudo em uma linha e eu deva criar um script de shell (o que não me agrada tanto, mas estou disposto a tentar).
Todas as dicas ou sugestões são bem-vindas! Obrigado!
find
), mas que pode estar resolvendo o seu problema real (conversão de arquivos de áudio), talvez você esteja interessado em ver audiotools.sourceforge.net e neste exemplo de caso (para macosx lion) invibe.net/ LaurentPerrinet / SciBlog / 22-04-2012Respostas:
Não tente analisar a
find
saída, exceto como último recurso. É importante perceber que, nos sistemas de arquivos Unix, os nomes de arquivos não são cadeias (um equívoco comum), mas blobs binários que podem conter qualquer caractere, exceto/
o caractere nulo. Analisar nomes de arquivos com segurança e corretamente é uma dor suficiente para que 99% das vezes você queira evitar fazê-lo completamente (veja como ased
expressão na resposta do @ yarek é cabeluda e até isso não cobre todos os casos) . Felizmente, neste caso, há uma abordagem muito mais simples:fonte
done
?sed
abordagem de pipe é que isso é muito mais seguro. Ainda é mais fácil ler do que a sopa de barra invertida regex, desde que você compreenda algumas construções básicas de script de shell.$arg
variável facilita muito a leitura.find
invocandosh
com uma sintaxe POSIX bastante portátil. Para obter mais detalhes, consulte a seção Expansão de parâmetros , a seção sobre comandos compostos que explica ofor
loop e a especificação POSIXfind
. Além desses recursos, eu ficaria feliz em responder a quaisquer perguntas específicas que você tiver.No Debian e Ubuntu, eu posso usar
rename 's/\(1\)//' *.m4a
para resolver seu problema.fonte
man rename
, mas na verdade não tenhorename
:-bash: rename: command not found
(which rename
não mostra nada).man -a rename
encontra aqui renomear (2) - o syscall e renomear (n) - o comando TCL. Não há renomear (1) nem o próprio utilitário lá.rename
é um script perl incluído nos exemplos incluídos em algumas instalações perl, e algumas distribuições o incluem no caminho porque é um comando conveniente. (@Hobbes talvez você pode encontrá-lo na internet)rename
é binário normal (não perl). No entanto, outra ressalva é que nem todas as versões derename
suporte regexes. A versão que eu tenho, por exemplo, só lhe permite fazer substituições de corda diretos, por exemplorename '(1)' '' *.m4a
rename
script Perl é instalado apenas pelo Debian e derivados. Outros sistemas Linux têm umrename
utilitário diferente (mostrado por Patrick). OSX não tem nenhum.No zsh, usando o zmv :
No segundo argumento (o novo nome)
$1
e$2
consulte os grupos entre parênteses(PATTERN)
no padrão de origem. Outra maneira de escrever essa renomeação éfonte
A abordagem a seguir permite visualizar / remover os comandos gerados antes de executá-los, e é muito portátil: deve funcionar não apenas em um mac, não apenas no bash, e não apenas no GNU sed; mesmo em sistemas sem o
find
comando (1), é possível substituí-lo pordu
(1) sem problemas.Se estiver satisfeito com os comandos impressos, execute novamente com o
| sh -x
anexo.Se estiver preocupado com os espaços nos nomes dos arquivos, adicione outro s para escapar de todos os espaços:
Se outros caracteres especiais são esperados, fica um pouco mais complicado:
A primeira função converte tudo
'
em uma forma que é feita literalmente quando está no meio da'...'
cadeia de caracteres com escape. A segunda função gera comandos mv cujos argumentos estão dentro'...'
.fonte
(
, e todos os outros caracteres especiais) ou adicionando aspas ao redor do nome do arquivo. Tentei modificar o seu comando, mas não consegui descobrir como adicionar aspas nos dois nomes de arquivos domv
comando. Uma das saídas resultantes do seu comando émv ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us(1).m4a ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us.m4a
. E se eu executar esse comando, recebo-bash: syntax error near unexpected token '('
.e
comando adicionando comando após a substituição. Por exemplofind . -name '*(1).m4a' | sed 's/\(.*\)(1).m4a$/mv & \1.m4a/e'
, executará o comando sem canalizar parash -x
.Aqui está um pequeno script que faz isso:
fonte
`find ...`