Bash를 사용하여 현재 날짜에 따라 이름이 지정된 새 파일로 이전 파일을 덮어씁니다.

Bash를 사용하여 현재 날짜에 따라 이름이 지정된 새 파일로 이전 파일을 덮어씁니다.

저는 Linux 초보자이고 파일 이름에 특정 날짜가 포함된 파일을 생성하려면 bash 스크립트를 만드는 데 도움이 필요합니다.

/backups/현재 날짜와 시간을 기준으로 접두어가 붙은 텍스트가 있는 파일을 생성하려는 디렉토리가 있습니다 /backups/backup_2023_09_15_14_00_00.txt. 예를 들어 이 부분은 이미 답변되었습니다.여기).

문제는 이전 백업 파일이 이미 존재하고(형식에 따라 이름이 지정됨 backup_****_**_**_**_**_**.txt) 새 파일이 성공적으로 생성된 경우 이전 백업 파일을 삭제하고 싶다는 것입니다.

이런 일을 할 수 있는 방법이 있나요?

답변1

다음 bash스크립트 조각은 위치 인수 목록(아래 명명된 배열을 사용하는 변형 참조)을 사용하여 이전 백업의 모든 경로 이름을 저장합니다. 새 백업이 생성된 후(여기에서는 시뮬레이션에 사용됨) touch이전에 기억된 백업이 삭제됩니다.

# Set backup dir variable and name of the new backup file.
backup_dir=/backups
printf -v backup_name 'backup_%(%Y_%m_%d_%H_%M_%S)T.txt' -1

# Remember any old backups.
shopt -s nullglob  # expand globs to nothing if no match
set -- "$backup_dir"/backup_????_??_??_??_??_??.txt

# Debugging output.
if [ "$#" -gt 0 ]; then
    printf 'Old file: %s\n' "$@"
else
    echo 'No old files'
fi

# Create the new backup at "$backup_dir/$backup_name".
# Terminate if not successful.
touch "$backup_dir/$backup_name" || exit

# Remove old files if there were any.
rm -f "$@"

위치 인수 목록 대신 오래된 백업 파일을 저장하려면 명명된 배열을 사용하세요. 디버그 출력을 생성하는 데 사용되는 할당 및 확장을 제외하면 oldfiles코드는 동일합니다 .rm

# Set backup dir variable and name of the new backup file.
backup_dir=/backups
printf -v backup_name 'backup_%(%Y_%m_%d_%H_%M_%S)T.txt' -1

# Remember any old backups.
shopt -s nullglob  # expand globs to nothing if no match
oldfiles=( "$backup_dir"/backup_????_??_??_??_??_??.txt )

# Debugging output.
if [ "${#oldfiles[@]}" -gt 0 ]; then
    printf 'Old file: %s\n' "${oldfiles[@]}"
else
    echo 'No old files'
fi

# Create the new backup at "$backup_dir/$backup_name".
# Terminate if not successful.
touch "$backup_dir/$backup_name" || exit

# Remove old files if there were any.
rm -f "${oldfiles[@]}"

새 백업이 성공적으로 생성되지 않으면 스크립트를 종료하는 대신 명령문에서 이전 파일을 삭제할 수 있습니다. if예를 들면 다음과 같습니다.

# Create the new backup.
# Remove old files if successful.
if touch "$backup_dir/$backup_file"
then
    rm -f "$@"    # or "${oldfiles[@]}" if you used the array and like typing longer things
fi

답변2

백업 파일만 원하는 경우 이에 대한 간단한 의사코드는 다음과 같습니다.

Capture list of existing backup files
create new backup file
if new filecreated OK, delete files in list 

단지 작은 파일을 복사하는 경우에는 create new backup file중복될 수 있으므로 실패할 가능성이 없습니다. 이 경우 새 파일을 만들기 전에 기존 파일을 삭제하세요. 그러나 대규모 tar/cpio 아카이브를 생성하거나 백엔드 서버로 오프로드하는 것은 또 다른 문제입니다.

하지만 좀 지루해요. 여러 개의 백업 파일을 유지하는 것은 어떻습니까? 주기적으로 생성된다는 것을 알고 있는 경우 다음을 수행할 수 있습니다.

find $BACKUPDIR -maxdepth 1 -mtime +7 -exec rm -f {} \;

지난 7일 이내에 생성되거나 수정된 ​​파일이 보관됩니다.

또는 여러 버전(아래 12개)을 유지하려는 경우...

ls -1 $BACKUPDIR/backup | sort | awk -v KEEP=12 '(NR>KEEP) { print $1 }' | xargs rm -f

답변3

다음을 수행할 수 있습니다.

# Save the list of files in the backup folder
files=$(ls /backups/backup_[0-9][0-9][0-9][0-9]_[0-9][0-9]_[0-9][0-9]_[0-9][0-9]_[0-9][0-9]_[0-9][0-9].txt)

# [Do your backup here, exit if it fails]

# Delete the files previously in the backup folder
for file in $files
do
    rm -f "${file}"
done

관련 정보