我需要一个命令来自动管理文件命名,以便进行备份。例如,我有一个名为 的文件test.txt
,有时我需要手动更新该文件,调用一个“重新计算” 的 bash 脚本test.txt
。
通常,在调用该 bash 脚本之前,我会手动复制该文件,格式如下:
cp test.txt test.txt.bk.x
其中x
,最后一个备份的编号为 + 1。
我想在我的 Bash 脚本开头放置一个命令,例如:
backup_cp -options_about_backup_filename_format test.txt
它会自动管理下一个备份文件的命名。我不需要遵循当前的文件命名模式,它可以是任何顺序格式,例如日志文件中的备份/var/log
n. 1 始终是最新备份,或者作为当前备份,其中备份编号按递增顺序排列。
如果该命令还可以自动删除最旧的备份,那就太棒了。
答案1
查看logrotate
命令。您使用配置文件指定如何备份旧版本。然后您可以调用:
logrotate -f config_file
配置文件的一个简单示例是:
/path/to/text.txt {
rotate 10
}
您还有许多其他选择,例如:dateext、postrotate、prerotate 等。
使用 dateext 时,日期会添加到文件名末尾,这样您就知道备份的创建时间。Post/Pre rotate 可以在备份前后执行一些任务。
如果您使用数字,它会与您习惯的略有不同。1 是最后一个文件,年龄随着数字而增长。
不要将配置文件放入/etc/logrotate.d/
,因为 logrotate 会自动从该目录运行配置文件。您只需要在需要时运行它,并将配置文件提供给 logrotate。
答案2
您可以生成一个数字,然后不断增加它并将其记录在文件中。
例如
#!/bin/bash
IDFILE="/path/to/file/.id_number"
ID=`cat $IDFILE`
#New ID for the next one
echo $[ID + 1] > $IDFILE
创建一个.id_number
以数字作为其内容的文件,然后您就可以开始使用它了。
答案3
我创建了一个能够处理类似任务的 bash 脚本。
脚本特点
该脚本将创建
target
文件或者目录. 它还可以处理多个文件和(或)目录. 名称新文件(或者新目录) 将为target.N
,其中N
是备份副本的连续编号。该脚本有两个选项:
--backup-chain=<chain name>
- 此选项将把字符串附加<chain name>
到备份文件的名称中,并且此链的编号将独立于其他链。--verbose-mode
- 此选项将附加到命令选项-v
列表中。cp
这里给出了一些使用示例:https://paste.ubuntu.com/25847541/
设置
1.创建可执行脚本文件,名为sbcp
(简单备份),位于,/usr/local/bin
可以作为 shell 命令访问:
sudo touch /usr/local/bin/sbcp
sudo chmod +x /usr/local/bin/sbcp
sudo nano /usr/local/bin/spcp
2.脚本内容sbcp
如下:
#!/bin/bash
# simple backup copy - sbcp
# Compose the info message - ref: https://askubuntu.com/a/583445/566421
info_message() {
printf "Please set target - one or more file or directory: \e[33msbcp 'file1' 'file2' 'dir1/file3' 'dir2'\e[0m\n"
printf "Use the option \e[33m--backup-chain='chain name'\e[0m or \e[33m--backup-chain=chain_name\e[0m to create different backup chains.\n"
printf "Use '\e[33msbcp *\e[0m' to make a backup copy for all items in the current directory, non recursively.\n"
}
# If the STDIN is not empty, then do the operations, else just output the info message
if [ ! -z "${@+x}" ]; then
# Check whether there options are set - this should be more elegant
for item in "$@"; do
# Find the backup chain name
if [[ "$item" =~ --backup-chain=.* ]]; then
BC="$(echo "${item}" | sed -e 's/--backup-chain=//' -e 's/\"//g' -e "s/'//g")"
[[ -z "$BC" ]] && BC="$BC" || BC=".$BC"
fi
# Check whether the option --backup-chain os set
if [[ "$item" =~ --verbose-mode.* ]]; then cp_options="-pvir"; else cp_options="-pir"; fi
done
# Check whether there are other input parameters different than the option --backup-chain, if there is not - output the info message and exit
if [ "$(echo "$@" | sed -e 's/--backup-chain=/./' -e 's/\"//g' -e "s/'//g")" == "${BC}" ]; then info_message && exit 1; fi
# Output the backup chain name
[[ -z "$BC" ]] && echo "Backup chain: .N" || echo "Backup chain: ${BC}.N"
# The main part - create backup copies
for item in "$@"; do
if [[ ! "$item" =~ --backup-chain=.* ]] && [[ ! "$item" =~ --verbose-mode.* ]]; then
LAST="$(ls -1d "${item}${BC}".* 2>/dev/null | awk -F'.' '{print $(NF)}' | grep -Po '[0-9]+' | sort | tail -n1)"
cp "$cp_options" "${item}" "${item}${BC}.$((LAST+1))"
fi
done
else
info_message
fi