次の名前の毎日のバックアップがあります。
yyyymmddhhmm.zip // pattern
201503200100.zip // backup from 20. 3. 2015 1:00
3日後にすべてのバックアップを削除するスクリプトを作成しようとしています。さらに、スクリプトはパターンと一致しないフォルダ内の他のすべてのファイルを削除できる必要があります(ただし、無効にするスイッチはスクリプト内にあります)。
ファイルの寿命を確認するために他のプログラムもファイルを操作して改ざんする可能性があるため、バックアップタイムスタンプを使用したくありません。
の助けを借りて:UNIXで5日以上古いファイルを削除する(タイムスタンプではなくファイル名の日付) 私は持っています:
#!/bin/bash
DELETE_OTHERS=yes
BACKUPS_PATH=/mnt/\!ARCHIVE/\!backups/
THRESHOLD=$(date -d "3 days ago" +%Y%m%d%H%M)
ls -1 ${BACKUPS_PATH}????????????.zip |
while read A DATE B FILE
do
[[ $DATE -le $THRESHOLD ]] && rm -v $BACKUPS_PATH$FILE
done
if [ $DELETE_OTHERS == "yes" ]; then
rm ${BACKUPS_PATH}*.* // but I don't know how to not-delete the files matching pattern
fi
しかし、続けてこう言います。
rm: missing operand
問題は何ですか?スクリプトを完成させる方法は何ですか?
答え1
コードの最初の問題は次のとおりです。分析するls
。つまり、ファイルまたはディレクトリ名にスペースが含まれていると簡単に破損する可能性があります。シェルワイルドカードを使用するか、代わりに使用する必要がありますfind
。
大きな問題は、データが正しく読み取られないことです。あなたのコード:
ls -1 | while read A DATE B FILE
決して埋められません$FILE
。の出力はls -1
ファイル名のリストなので、そのファイル名にスペースが含まれていない場合は、read
指定した4つの変数の最初の変数のみが入力されます。
以下はスクリプトの作業バージョンです。
#!/usr/bin/env bash
DELETE_OTHERS=yes
BACKUPS_PATH=/mnt/\!ARCHIVE/\!backups
THRESHOLD=$(date -d "3 days ago" +%Y%m%d%H%M)
## Find all files in $BACKUPS_PATH. The -type f means only files
## and the -maxdepth 1 ensures that any files in subdirectories are
## not included. Combined with -print0 (separate file names with \0),
## IFS= (don't break on whitespace), "-d ''" (records end on '\0') , it can
## deal with all file names.
find ${BACKUPS_PATH} -maxdepth 1 -type f -print0 | while IFS= read -d '' -r file
do
## Does this file name match the pattern (13 digits, then .zip)?
if [[ "$(basename "$file")" =~ ^[0-9]{12}.zip$ ]]
then
## Delete the file if it's older than the $THR
[ "$(basename "$file" .zip)" -le "$THRESHOLD" ] && rm -v -- "$file"
else
## If the file does not match the pattern, delete if
## DELETE_OTHERS is set to "yes"
[ $DELETE_OTHERS == "yes" ] && rm -v -- "$file"
fi
done
答え2
FreeBSDで使用されている:例:/usr/home/foobarで5760分(4日)より古いfoobar所有のすべてのファイルを見つけて削除します。
find /usr/home/foobar -user foobar -type f -mmin +5760 -delete
答え3
sed
との間の行を忘れないでください。この行が重要です。ls -1
while read
私が提案したい最初の質問は次のとおりです。 (awkの交換に対応するsedが見つかりません。)
ls -1 ${BACKUPS_PATH}????????????.zip |\
awk -F. '{printf "%s %s\n",$1,$0 ;}' |\
while read DATE FILE
do
[[ $DATE -le $THRESHOLD ]] && rm -v $BACKUPS_PATH$FILE
done
提供されるシェル操作はテスト用に少なくとも37ビットです$DATE -le $THRESHOLD
。