Como o Bash pode renomear uma série de pacotes para remover seus números de versão? Tenho brincado com os dois expr
e %%
, sem sucesso.
Exemplos:
Xft2-2.1.13.pkg
torna-se Xft2.pkg
jasper-1.900.1.pkg
torna-se jasper.pkg
xorg-libXrandr-1.2.3.pkg
torna-se xorg-libXrandr.pkg
bash
shell
file-rename
Jeremy L
fonte
fonte
Respostas:
Você pode usar o recurso de expansão de parâmetros do bash
As citações são necessárias para nomes de arquivos com espaços.
fonte
rename "s/-[0-9.]*//" *.pkg
Se todos os arquivos estiverem no mesmo diretório, a sequência
fará o seu trabalho. O comando sed criará uma sequência de comandos mv , que você pode canalizar para o shell. É melhor primeiro executar o pipeline sem o trailing
| sh
para verificar se o comando faz o que você deseja.Para percorrer vários diretórios, use algo como
Observe que no sed a sequência de agrupamento da expressão regular são colchetes precedidos por uma barra invertida
\(
e\)
, em vez de colchetes simples(
e)
.fonte
ls
em scripts. A primeira variedade pode ser alcançada comprintf '%s\n' * | sed ...
e com alguma criatividade, você provavelmente também pode se livrarsed
dela. O Bashprintf
oferece um'%q'
código de formato que pode ser útil se você tiver nomes de arquivo que contenham metacaracteres de shell literais.Vou fazer algo assim:
supostamente todos os seus arquivos estão no diretório atual. Se não, tente usar find conforme recomendado acima por Javier.
EDIT : Além disso, esta versão não usa nenhum recurso específico do bash, como os outros acima, o que leva você a mais portabilidade.
fonte
Aqui está um POSIX quase equivalente à resposta atualmente aceita . Isso troca a
${variable/substring/replacement}
expansão de parâmetro apenas do Bash por uma que está disponível em qualquer shell compatível com Bourne.O parâmetro expansion
${variable%pattern}
produz o valor devariable
com qualquer sufixo que correspondapattern
removido. (Também é${variable#pattern}
necessário remover um prefixo.)Eu mantive o subpadrão
-[0-9.]*
da resposta aceita, embora talvez seja enganoso. Não é uma expressão regular, mas um padrão glob; portanto, não significa "um traço seguido de zero ou mais números ou pontos". Em vez disso, significa "um travessão, seguido por um número ou um ponto, seguido por qualquer coisa". O "qualquer coisa" será a correspondência mais curta possível, não a mais longa. (O Bash oferece##
e%%
para cortar o prefixo ou sufixo mais longo possível, em vez do mais curto.)fonte
Podemos presumir que
sed
está disponível em qualquer * nix, mas não podemos ter certeza de que suportarásed -n
a geração de comandos mv. ( NOTA: Apenas GNUsed
faz isso.)Mesmo assim, bash builtins e sed, podemos rapidamente criar uma função shell para fazer isso.
Uso
Criação de pastas de destino:
Uma vez
mv
que não cria pastas de destino automaticamente, não podemos usar nossa versão inicial dosedrename
.É uma mudança bastante pequena, então seria bom incluir esse recurso:
Precisaremos de uma função de utilidade
abspath
(ou caminho absoluto) já que o bash não tem essa função.Assim que tivermos isso, podemos gerar a (s) pasta (s) de destino para um padrão sed / rename que inclui uma nova estrutura de pastas.
Isso garantirá que saibamos os nomes de nossas pastas de destino. Quando renomearmos, precisaremos usá-lo no nome do arquivo de destino.
Aqui está o script com reconhecimento de pasta completo ...
Claro, ele ainda funciona quando não temos pastas de destino específicas também.
Se quisermos colocar todas as músicas em uma pasta,
./Beethoven/
podemos fazer o seguinte:Uso
Rodada de bônus ...
Usando este script para mover arquivos de pastas para uma única pasta:
Supondo que desejamos reunir todos os arquivos correspondentes e colocá-los na pasta atual, podemos fazer isso:
Nota sobre padrões de regex sed
Regras regulares de padrão sed se aplicam a este script, esses padrões não são PCRE (Expressões regulares compatíveis com Perl). Você poderia ter estendido a sintaxe de expressão regular do sed, usando
sed -r
oused -E
dependendo da sua plataforma.Consulte o POSIX compatível
man re_format
para uma descrição completa dos padrões de expressão regular básica e estendida sed.fonte
Acho que renomear é uma ferramenta muito mais simples de usar para esse tipo de coisa. Eu encontrei no Homebrew para OSX
Para o seu exemplo, eu faria:
O 's' significa substituto. O formato é s / searchPattern / replacement / files_to_apply. Você precisa usar regex para isso, o que exige um pouco de estudo, mas vale a pena o esforço.
fonte
for
esed
etc. é bom, mas é muito mais simples e rápido de usarrename
se você fizer isso com frequência.rename
comando; Além disso, alguns terão um diferenterename
comando com características diferentes, sintaxe e / ou opções. Isso se parece com o Perl,rename
que é bastante popular; mas a resposta deve realmente esclarecer isso.melhor uso
sed
para isso, algo como:descobrir a expressão regular é deixado como um exercício (assim como lidar com nomes de arquivos que incluem espaços)
fonte
Isso parece funcionar assumindo que
retire o .pkg, depois retire - ..
fonte
-e
. Exsed -e 's/\.pkg//g' -e 's/-.*//g'
.ls
saída e cite suas variáveis. Consulte também shellcheck.net para diagnosticar problemas comuns e antipadrões em scripts de shell.Eu tinha vários
*.txt
arquivos para serem renomeados como.sql
na mesma pasta. abaixo funcionou para mim:fonte
Obrigado por essas respostas. Eu também tive algum tipo de problema. Movendo arquivos .nzb.queued para arquivos .nzb. Tinha espaços e outras falhas nos nomes dos arquivos e isso resolveu meu problema:
É baseado na resposta de Diomidis Spinellis.
O regex cria um grupo para todo o nome do arquivo e um grupo para a parte anterior a .nzb.queued e, a seguir, cria um comando de movimentação do shell. Com as cordas entre aspas. Isso também evita a criação de um loop no script de shell porque isso já é feito pelo sed.
fonte
-n
opção da mesma maneira.