简体   繁体   English

在 bash 中创建文件的备份

[英]Create a backup of a file in bash

I want to write into a file in a bash script but I want to make sure that the file is backed up if it exists and I also want to avoid overwriting any existing backups.我想写入 bash 脚本中的文件,但我想确保该文件是否存在,并且我还想避免覆盖任何现有备份。

So basically I have $FILE, if this exists, I want to move $FILE to $FILE.bak if it does not already exist, otherwise to $FILE.bak2, $FILE.bak3, etc.所以基本上我有 $FILE,如果它存在,如果它不存在,我想将 $FILE 移动到 $FILE.bak,否则移动到 $FILE.bak2、$FILE.bak3 等。

Is there a shell command for this?是否有针对此的 shell 命令?

Using a function to find the next available name:使用 function 查找下一个可用名称:

#!/usr/bin/env bash
function nextsuffix {
    local name="$1.bak"
    if [ -e "$name" ]; then
        printf "%s" "$name"
    else
        local -i num=2
        while [ -e "$name$num" ]; do
            num+=1
        done
        printf "%s%d" "$name" "$num"
    fi
}

mv "$1" "$(nextsuffix "$1")"

If foo.bak already exists, it just loops until a given foo.bakN filename doesn't exist, incrementing N each time.如果foo.bak已经存在,它只会循环直到给定的foo.bakN文件名不存在,每次递增N

You can just output to a file with a date.您可以只 output 到带有日期的文件。

FILE=~/test
echo "123" >> $FILE.$(date +'%Y%d%m')

If you want the numbers logrotate seems to be most ideal.如果你想要数字 logrotate 似乎是最理想的。

cp "$FILE" "$FILE.bak$(( $(grep -Eo '[[:digit:]]+' <(sort -n <(for fil in $FILE.bak*;do echo $fil;done) | tail -1 )) + 1 ))"

Breaking the commands down分解命令

sort -n <(for fil in $FILE.bak*;do echo $fil;done) | tail -1

List the last file in the directory which is sorted in numeric form列出目录中以数字形式排序的最后一个文件

grep -Eo '[[:digit:]]+' <(sort -n <(for fil in $FILE.bak*;do echo $fil;done) | tail -1 ))

Strip out everything but the digits去掉除数字以外的所有内容

(( $(grep -Eo '[[:digit:]]+' <(sort -n <(for fil in $FILE.bak*;do echo $fil;done) | tail -1 )) + 1 ))

Add one to the result在结果中加一

For posterity, my function with changes inspired by @Shawn's answer对于后代,我的 function 的更改灵感来自@Shawn 的回答

backup() {
    local file new n=0
    local fmt='%s.%(%Y%m%d)T_%02d'
    for file; do
        while :; do
            printf -v new "$fmt" "$file" -1 $((++n))
            [[ -e $new ]] || break
        done
        command cp -vp "$file" "$new"
    done
}

I like to cp not mv .我喜欢cp而不是mv

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM