/ / Depuração do one-liner do Perl para renomear arquivos - perl

Depurando o one-liner Perl para renomear arquivos - perl

Eu estava testando / experimentando esta uma linha de Perl, e eu estou tentando descobrir o que aconteceu com os arquivos. Eu não vejo mais os arquivos. Eu deletei ou o que deu errado?

Exemplo de nomes de arquivos listados (original):

IMG_0178.JPG
IMG_0182.JPG
IMG_0183.JPG
IMG_0184.JPG
IMG_0186.JPG

Eu queria simplesmente mudar a extensão do arquivo para minúsculas (.jpg):

perl -e"while(<*.JPG>) { s/JPG$/jpg/; rename <*.jpg>, $_ }"

Respostas:

9 para resposta № 1

Não use rename com uma glob. Use escalares. Tente atribuir o nome do arquivo a uma nova variável antes da substituição e renomeie o nome antigo para o modificado, assim:

perl -e"while(<*.JPG>) { ($new = $_) =~ s/JPG$/jpg/; rename $_, $new }"

Verifique a saída com ls -1:

IMG_0178.jpg
IMG_0182.jpg
IMG_0183.jpg
IMG_0184.jpg
IMG_0186.jpg

4 para resposta № 2

Estranhamente, seu código deve fazer o que você queria.

Um arquivo glob como <*.JPG> no contexto escalar retornará o próximo arquivo que corresponde ao padrão e while e rename aplicar contexto escalar, os dois globs retornam o mesmo valor em cada iteração.

while (<*.JPG>) {
s/JPG$/jpg/;
rename <*.jpg>, $_;
}

Na primeira iteração do loop $_ está configurado para IMG_0178.JPG pelo whileea substituição define o tipo de arquivo para minúsculas.

Então na renomeação <*.jpg> é executado em contexto escalar e retorna novamente IMG_0178.JPG - o primeiro arquivo na mesma lista, porque os nomes de arquivos do Windows não fazem distinção entre maiúsculas e minúsculas.

Então, finalmente, a renomeação executa rename "IMG_0178.JPG", "IMG_0178.jpg" como requerido.

Reescrevendo rename assim mostra isso claramente

sub ren($$) {
print "$_[0] -> $_[1]n";
}

while (my $file = <*.JPG>) {
$file =~ s/JPG$/jpg/;
ren <*.JPG>, $file;
}

saída

IMG_0178.JPG -> IMG_0178.jpg
IMG_0182.JPG -> IMG_0182.jpg
IMG_0183.JPG -> IMG_0183.jpg
IMG_0184.JPG -> IMG_0184.jpg
IMG_0186.JPG -> IMG_0186.jpg

Então você tem sorte, e seus arquivos deveriam ter sido renomeados como você queria.

Mas não "t faça isso. Em particular, você deve executar o programa com uma declaração impressa no lugar de quaisquer operações críticas para que você possa ver o que vai acontecer.

Isso seria melhor, pois o id faz mais claramente o que se pretende

perl -e "($f = $_) =~ s/JPG$/jpg/i and rename $_, $f while <*.JPG>"