Hay varios puntos de falla posibles en su secuencia de comandos. En primer lugar, rm *.old*
usará globbing para crear una lista de todos los archivos coincidentes, y eso puede tratar con nombres de archivos que contienen espacios en blanco. Sin embargo, su script asigna una variable a cada resultado del glob y lo hace sin citar. Eso se romperá si los nombres de sus archivos contienen espacios en blanco. Por ejemplo:
$ 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 puede ver, el bucle falló para el archivo con espacios en su nombre. Para hacerlo correctamente, deberá citar la variable:
$ for i in ./*; do oldfile="$i"; rm -v "$oldfile"; done
removed './file name with spaces.old.txt'
removed './file.old.txt'
El mismo problema se aplica a casi todos los usos de $i
su secuencia de comandos. Usted debe siempre citar sus variables .
El siguiente problema posible es que parece esperar que *.old.*
coincida con los archivos con la extensión .old
. No lo hace. Coincide con "0 o más caracteres" ( *
), luego a .
, luego "viejo", luego otro .
y luego "0 o más caracteres nuevamente". Esto significa que no coincidirá con algo como file.old
, sino solo 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
Entonces, no hay rival para el enemigo file.old
. En cualquier caso, su script es mucho más complejo de lo necesario. Prueba este en su lugar:
#!/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
Tenga en cuenta que agregué -v
a las declaraciones rm
y cp which does the same thing as what you were doing with your
echo`.
Esto no es perfecto ya que cuando encuentre, por ejemplo, file.old
que se eliminará y, más adelante, el script intentará copiarlo y fallará ya que el archivo ya no existe. Sin embargo, no ha explicado lo que su script realmente está intentando hacer, así que no puedo arreglarlo por usted a menos que nos diga lo que realmente está tratando de lograr.
Si lo que desea es i) eliminar todos los archivos con la .old
extensión y ii) agregar la .old
extensión a cualquier archivo existente que no lo tenga, todo lo que realmente necesita es:
#!/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
rm *.old.*
que elimina estos archivos pero no el archivo de respaldo file.old. Estoy tratando de hacer eso en mi guión. Gracias