Eu tenho um conjunto de arquivos com prefixo, digamos "pre_", em uma máquina Linux e só quero renomear todos esses arquivos removendo-os. Aqui está o código perl que escrevi, não apresenta nenhum erro, mas o trabalho não está concluído.
#!/usr/bin/perl -w
my @files = `ls -1 | grep -i \"pre_.*\"`;
foreach $file ( @files )
{
my @names = split(/pre_/, $file);
my $var1 = $names[1];
'mv "$file" "$var1"';
}
Você não está executando nada. Quando você coloca algo entre aspas simples (
''
), isso é apenas uma string, então'mv "$file" "$var1"'
não é um comando, é uma string e não faz nada. Uma string por si só é apenas uma declaração verdadeira. Para executar o comando, você precisa usar:( Não
que introduziria uma vulnerabilidade de injeção de comando).system("mv '$file' '$var1'")
Mas não há necessidade disso,
perl
tem umarename()
função, então você pode fazer:Em seguida, você realmente não deve analisar a saída de
ls
, que é uma ideia muito ruim e frágil . Também é completamente desnecessário em Perl (ou qualquer outra linguagem de programação). Se você deseja corresponder a todos os arquivos no diretório atual que contém a stringpre_
(que é o que vocêgrep
faz - você não precisa dogrep
, a propósito, você poderia ter usado apenasls -d -- *pre_*
), você pode usarglob()
assim:Então, juntando tudo isso, é isso que você estava tentando fazer:
Mas isso não é realmente uma boa ideia. Se você tiver dois arquivos com o mesmo prefixo (por exemplo
pre_file1
eapre_file1
), o primeiro arquivo será substituído pelo segundo arquivo, pois, neste exemplo, ambos os arquivos seriam renomeadosfile1
porque seu comando removeriapre_
e tudo antes dele. Então você pode adicionar um aviso e pular esses arquivos:Claro, tudo isso é reinventar a roda. Você pode apenas instalar
perl-rename
(no Debian, Ubuntu, etc. runapt install rename
, em outros sistemas pode ser chamadoprename
ouperl-rename
), e então você pode fazer (embora isso não diferencie maiúsculas de minúsculas, ele apenas encontra arquivos contendopre_
):As
-n
causasrename
para apenas imprimir o que faria, sem realmente renomear. Assim que tiver certeza de que a renomeação funciona conforme o esperado, execute o comando novamente sem o-n
para realmente renomear os arquivos.Aqui, o shell passa todos os arquivos (não ocultos)
rename
erename
ignorará os arquivos cujo nome operl
código não altera. Você também pode dizer ao shell para passar apenas os nomes de arquivo que não diferenciampre_
maiúsculas de minúsculas com./~(i)*pre_*
inksh93
,./(#i)*pre_*
inzsh -o extendedglob
, definindo anocaseglob
opção globalmente inbash
,zsh
ouyash
ou use./*[pP][rR][eE]_*
.A ferramenta que você precisa já existe como
rename
(dependendo da sua distro tambémperl-rename
ouprename
)Use
-n
para uma simulação e-v
para listar as renomeações.Nota: Não confundir com o
rename
comandoutil-linux
que funciona de forma diferente.... Outras alternativas de renomeação também ( em vez de "reinventar a roda" ) são ...
Usando
mmv
assim:Ou no Z Shell(
zsh
) usando sua função internazmv
assim:Aviso:
-n
em ambos os casos acima é para um dry-run seguro ... Quando estiver satisfeito com a saída, remova-a ou substitua-a por-v
( para detalhamento ) para que a renomeação real aconteça.