Inicie um shell para usar os operadores de expansão de parâmetros do shell:
find ~/tmp -name '*.log' -type f -exec sh -c '
for file do
mv -i -- "$file" "${file%.*}"
done' sh {} +
Observe que você não deseja fazer isso em /tmp
ou em qualquer diretório gravável por outros, pois isso permitiria que usuários maliciosos o fizessem renomear arquivos .log
arbitrários no sistema de arquivos¹ (ou mover arquivos para qualquer diretório²) .
Com algumas implementações find
e mv
, você pode usar find -execdir
e mv -T
para torná-lo mais seguro:
find /tmp -name '*.log' -type f -execdir sh -c '
for file do
mv -Ti -- "$file" "${file%.*}"
done' sh {} +
Ou use rename
(a variante perl) que faria apenas uma chamada de sistema rename()
para não tentar mover arquivos para outros sistemas de arquivos ou diretórios ...
find /tmp -name '*.log' -type f -execdir rename 's/\.log$//' {} +
Ou faça tudo em perl
:
perl -MFile::Find -le '
find(
sub {
if (/\.log\z/) {
$old = $_;
s/\.log\z//;
rename($old, $_) or warn "rename $old->$_: $!\n"
}
}, @ARGV)' ~/tmp
Mas note que perl
do Find::File
(ao contrário do GNU find
) não faz um diretório seguro traversal³, então isso não é algo que você gostaria de fazer no /tmp
.
Notas.
¹ um invasor pode criar um arquivo /tmp/. /auth.log
e entre find
localizá-lo e mv
movê-lo (e essa janela pode ser facilmente arbitrariamente grande) substitua o diretório "/tmp/. "
por um link simbólico para /var/log
resultando em /var/log/auth.log
sendo renomeado para /var/log/auth
² Muito pior, um invasor pode criar um /tmp/foo.log
malicioso crontab
por exemplo e /tmp/foo
um link simbólico para /etc/cron.d
e fazer você mover esse crontab para /etc/cron.d
. Essa é a ambigüidade com mv
(também se aplica a cp
e ln
pelo menos) que pode ser mover para e mover para . O% GNUmv
corrige com suas opções -t
( em ) e -T
( para ).
³ File::Find
atravessa o diretório fazendo chdir("/tmp"); read content; chdir("foo") ...; chdir("bar"); chdir("../..")...
. Então, alguém pode criar um diretório /tmp/foo/bar
e, no momento certo, renomeá-lo para /tmp/bar
, para que chdir("../..")
coloque você em /
.