I have the following files in my script's directory:
backup-001.bak backup-002.bak...backup-007.bak
I am trying to rename them in pure bash so that I get:
backup-002.bak backup-003.bak...backup-008.bak
I put together the following simple script which should iteratively rename said files; however, after I run it I end up with only one file backup-008.bak
. What am I doing wrong here?
i=2
for file in backup-00[0-7].bak; do
newname="backup-00$((i)).bak"
mv -- "$file" "$newname"
(( i))
done
CodePudding user response:
for i in {7..1}; do
mv "backup-00$i.bak" "backup-00$((i 1)).bak" ||
break
done
Only works for 0-9 (or 100-200 etc) - bash arithmetic won't return zero padded numbers.
CodePudding user response:
You're renaming backup-000.bak
to backup-001.bak
. Then you rename backup-001.bak
to backup-002.bak
. This renames the file you created on the previous iteration. And so on through all the files, so you end up renaming backup-000.bak
to backup-008.bak
.
You should process the files in reverse order:
for ((i = 7; i >= 1; i--)); do
oldname="backup-00$i.bak"
newname="backup-00$((i 1)).bak"
if [ -f "$oldname" ]
then
mv -- "$oldname" "$newname"
fi
done
BTW, Linux has a program logrotate
that can automate this.
CodePudding user response:
Considering a minimum index of 1 and a maximum index index of 7; here is a POSIX-shell friendly implementation with correct handling of backup roll and ignoring non-existent backup files.
#!/usr/bin/env sh
i=7
newname=$(printf 'backup-d.bak' $i)
while [ $i -gt 1 ]; do
i=$((i - 1))
oldname=$(printf 'backup-d.bak' $i)
echo mv -f -- "$oldname" "$newname" 2>/dev/null || :
newname=$oldname
done