Por que `renomear` se comporta de maneira diferente sempre que uso o caminho completo em vez do caminho atual?

Por que `renomear` se comporta de maneira diferente sempre que uso o caminho completo em vez do caminho atual?

Ok, estourespondendo a uma perguntaonde o OP possui vários repositórios no Ubuntu que podem estar causando problemas na instalação de software não relacionado. Eu recomendo desabilitar os PPAs usando um único liner renamee seguir uma série de instruções. Tudo bem, e deixo essa pergunta como respondida... não. Resultados que renamenão se comportaram como esperado:

sudo rename s/list/list\.disable/g /etc/apt/sources.list.d/*.list

Com isso, espero que rename examine /etc/apt/sources.list.d/qualquer arquivo que termine em .liste substitua .listpor .list.disable. Recebi outra resposta com quase o mesmo comando, mas o OP nunca deu feedback, e estou lançando a teoria sem testar primeiro. Então, é para minha surpresa que o OP encontra problemas com a linha:

Can't rename /etc/apt/sources.list.d/iaz-battery-status-quantal.list /etc/apt/sources.list.disable.d/iaz-battery-status-quantal.list.disable: No such file or directory
Can't rename /etc/apt/sources.list.d/ubuntu-wine-ppa-quantal.list /etc/apt/sources.list.disable.d/ubuntu-wine-ppa-quantal.list.disable: No such file or directory
Can't rename /etc/apt/sources.list.d/webupd8team-java-raring.list /etc/apt/sources.list.disable.d/webupd8team-java-raring.list.disable: No such file or directory

Tenho uma sensação estranha, então testo a teoria sozinho e vejo o mesmo resultado. Então,sempre que você tem um problema normalmente é regex, não? Eu mudei o regex de muitas maneiras distorcidas:

  • s/.list/.list.disable/g
  • s/.list/.list.disable/g
  • /list/list.disable/
  • outras combinações que não me lembro

Bem, decidi que regex não era o problema, então olhei para o seletor, alterei-o /etc/apt/sources.list.d/*e reciclei o teste de regex. Sem alegria. Ficando um pouco frustrado eu faço touch some.liste aplico meu comando

rename s/\.list/\.list\.disable/g *

Bingo! Agora me sinto totalmente trollado. Corrijo minha resposta e continuo com minha vida... não! Isto não é aceitável. Por que? Procuro o manual que, para minha surpresa, usa apenas exemplos de caminhos atuais. Isso é normal? Ou será que a função não foi implementada? Ou devo começar a desconfiar das minhas teorias?

Responder1

Use o -nparâmetro para executar renameem modo de teste que é muito útil quando você deseja testar seu padrão:

martin@martin ~ % rename -n s/list/list.disable/g /etc/apt/sources.list.d/*.list | sed 's/renamed as/\n =>/g'
[...]
/etc/apt/sources.list.d/spotify.list 
 => /etc/apt/sources.list.disable.d/spotify.list.disable
/etc/apt/sources.list.d/steam.list 
 => /etc/apt/sources.list.disable.d/steam.list.disable
[...]

O erro óbvio aqui é que o padrão listcorresponde , então você está tentando renomear a pasta e os arquivos contidos.sources.list.d

Use este padrão:

rename -n 's/\.list$/.list.disable/' /etc/apt/sources.list.d/*.list | sed 's/renamed as/\n =>/g'
[...]
/etc/apt/sources.list.d/spotify.list 
 => /etc/apt/sources.list.d/spotify.list.disable
/etc/apt/sources.list.d/steam.list 
 => /etc/apt/sources.list.d/steam.list.disable
[...]

As diferenças são:

  1. Citar the .no padrão de pesquisa as \.garante que o ponto corresponda apenas a um ponto real, e não a qualquer caractere (é o que geralmente faz um ponto sem aspas em uma regex).

  2. A $lista posterior significa "fim da string". Ele garante que apenas o ".list" no final do nome do arquivo corresponda e seja substituído, e não um ".list" que esteja em algum outro lugar no caminho ou no nome do arquivo.

  3. Você não precisa colocar o ponto entre aspas na string de substituição; ".list.disable" portanto funciona sem barras invertidas, porque .não tem mais um significado especial ali.

  4. Observe também que citei o regex entre aspas simples para evitar que o shell o modifique de alguma forma.

Responder2

O problema é usar a opção global gquando você realmente deveria ter ancorado o padrão. Como você escreveu:

s/a/b/g

substitui cada a por b em qualquer lugar da string. Isso está fazendo com que você tente renomear caminhos para os quais não existe diretório. É também por isso que o problema desapareceu quando você fez a operação dentro do diretório, então havia apenas uma correspondência para substituir.

Eu acho que você poderia ter pretendido ancorar o padrão

s/\.list$/.list.disable/

o que teria evitado a tentativa de mover um arquivo para o diretório /etc/apt/sources.list.disable.d/ que não existe (portanto, você não pode mover um arquivo para ele).

informação relacionada