Existem vários pontos de falha possíveis no seu script. Antes de mais nada, rm *.old*
usará globbing para criar uma lista de todos os arquivos correspondentes e que podem lidar com nomes de arquivos contendo espaço em branco. Seu script, no entanto, atribui uma variável a cada resultado do glob e faz isso sem citar. Isso irá quebrar se seus nomes de arquivo contiverem espaços em branco. Por exemplo:
$ ls
'file name with spaces.old.txt' file.old.txt
$ rm *.old.* ## works: both files are deleted
$ touch "file.old.txt" "file name with spaces.old.txt"
$ for i in ./*; do oldfile=$i; rm -v $oldfile; done
rm: cannot remove './file': No such file or directory
rm: cannot remove 'name': No such file or directory
rm: cannot remove 'with': No such file or directory
rm: cannot remove 'spaces.old.txt': No such file or directory
removed './file.old.txt'
Como você pode ver, o loop falhou para o arquivo com espaços em seu nome. Para fazer isso corretamente, você precisaria citar a variável:
$ for i in ./*; do oldfile="$i"; rm -v "$oldfile"; done
removed './file name with spaces.old.txt'
removed './file.old.txt'
O mesmo problema se aplica a praticamente todo uso de $i
em seu script. Você deve sempre citar suas variáveis .
O próximo problema possível é que você espera que *.old.*
corresponda aos arquivos com a extensão .old
. Não faz. Ele corresponde a "0 ou mais caracteres" ( *
), depois a .
, depois "old", depois outro .
e "0 ou mais caracteres novamente". Isso significa que não corresponde a algo como file.old
, mas apenas algo como 'file.old.foo:
$ ls
file.old file.old.foo
$ for i in *; do if [[ "$i" == *.old.* ]]; then echo $i; fi; done
file.old.foo
Portanto, não há correspondência para file.old
. Em qualquer caso, seu script é muito mais complexo do que o necessário. Tente este em vez disso:
#!/bin/bash
for i in *; do
if [[ -f "$i" ]]; then
if [[ "$i" == *.old ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i doesn't have an .old extension"
fi
cp -v "$i" "$i".old
else
echo "$i is not a file"
fi
done
Observe que adicionei -v
às declarações rm
e cp which does the same thing as what you were doing with your
echo '.
Isso não é perfeito desde quando você encontra, por exemplo, file.old
, que será removido e, mais tarde, o script tentará copiá-lo e falhar, pois o arquivo não existe mais. No entanto, você não explicou o que seu script está realmente tentando fazer, então não posso consertar isso para você, a menos que você nos diga o que realmente está tentando realizar.
Se o que você quer é i) remover todos os arquivos com a extensão .old
e ii) adicionar a extensão .old
a todos os arquivos existentes que não a possuem, tudo o que você realmente precisa é:
#!/bin/bash
for i in *.old; do
if [[ -f "$i" ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i is not a file"
fi
done
## All the ,old files have been removed at this point
## copy the rest
for i in *; do
if [[ -f "$i" ]]; then
## the -v makes cp report copied files
cp -v "$i" "$i".old
fi
done