Bagaimana opsi “1 bulan lalu” dalam perintah tanggal bekerja?

22

Saya tidak yakin apakah ini mendapatkan tanggal yang lalu dalam hari ini atau jika hanya butuh 30 atau 31 hari untuk itu.

misalnya

Jika tanggal saat ini March 28th, 1 bulan yang lalu harus February 28th, tetapi apa yang terjadi ketika itu March 30th?

Skenario

Saya ingin mencadangkan beberapa file setiap hari, skrip akan menyimpan file ini dalam tanggal saat ini dengan $(date +%Y%m%d)format, seperti 20150603_bckp.tar.gz, kemudian ketika bulan berikutnya tiba, hapus semua file dalam 1 bulan yang lalu kecuali file ke-1 dan ke-15, jadi ini adalah kondisi saya:

past_month = $(date -d "-1 month" +%Y%m%d)
day = $(date +%d)
if [ "$day" != 01 ] && [ "$day" != 15 ]
then
    rm /path/of/files/${past_month}_bckp.tar.gz
    echo "Depuration done"
else
    echo "Keep file"
fi

Tapi saya ingin tahu, apa yang akan terjadi ketika tanggal 30, 31 atau bahkan contoh Februari lalu? Itu akan menyimpan file-file itu? atau hapus file hari ke-1?

Ketika tanggal 31 masa depurasi akan dieksekusi, jadi jika bulan lalu hanya memiliki 30 hari, ini akan menghapus file hari pertama?

Saya harap saya mengisyaratkan.

Takomi
sumber
1
Tidakkah Anda tahu saya ada di sini pada 30 Maret karena alasan yang tepat ini
user7203

Jawaban:

24

- 1 monthakan mengurangi satu dari nomor bulan, dan kemudian jika tanggal yang dihasilkan tidak valid ( February 30, misalnya), sesuaikan sehingga valid. Begitu December 31 - 1 monthjuga December 1, bukan hari di bulan November, dan March 31 - 1 monthitu March 3(kecuali dieksekusi pada tahun kabisat).

Berikut ini kutipan dari halaman info untuk Gnu date(yang merupakan dateversi yang mengimplementasikan sintaksis ini), yang mencakup saran bagus untuk membuat aritmatika lebih kuat:

Fuzz dalam unit dapat menyebabkan masalah dengan item relatif. Misalnya, 2003-07-31 -1 monthdapat mengevaluasi ke 2003-07-01, karena 2003-06-31 adalah tanggal yang tidak valid. Untuk menentukan bulan sebelumnya lebih andal, Anda dapat meminta bulan sebelum tanggal 15 bulan berjalan. Sebagai contoh:

    $ date -R
    Thu, 31 Jul 2003 13:02:39 -0700
    $ date --date='-1 month' +'Last month was %B?'
    Last month was July?
    $ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!'
    Last month was June!

Peringatan lain, juga dikutip dari halaman info:

Selain itu, berhati-hatilah saat memanipulasi tanggal di sekitar perubahan jam seperti lompatan siang hari. Dalam beberapa kasus ini telah menambah atau mengurangi sebanyak 24 jam dari jam, sehingga sering kali bijaksana untuk mengadopsi waktu universal dengan mengatur TZvariabel lingkungan UTC0 sebelum memulai perhitungan kalender.

Rici
sumber
Saya ragu di sini, khususnya dalam situasi Februari ... Ketika 29 Maret, 30 atau 31 mungkin butuh angka berikut dari bulan lalu jika yang saat ini tidak ada, jadi dalam tiga situasi ini mungkin diperlukan 1 Maret bukan? Karena jika 29 Maret, 30, 31 dan kemudian 1, 2, 3 seperti yang Anda katakan, maka 1 April akan menjadi 4 Maret karena restrukturisasi (saya tidak tahu apakah itu dikatakan dengan baik) yang dibuat, bagaimana menurut Anda ?
tachomi
Satu bulan sebelum 1 April adalah 1 Maret dan satu bulan sebelum 1 Maret adalah 1 Februari. Ini bukan masalah. Masalahnya adalah bahwa satu bulan sebelum 31 Mei adalah 1 Mei karena 31 April tidak ada. Anda harus memeriksa nomor hari dari tanggal satu bulan yang lalu, bukan hari dari tanggal saat ini.
rici
2
Doh! Fakta bahwa "satu bulan yang lalu" dari beberapa hari tertentu dalam bulan apa pun dapat menghasilkan bulan yang sama bukanlah apa yang saya harapkan dari suatu dateimplementasi; dalam buku saya ini kontra-intuitif secara semantik. - Terima kasih telah menunjukkan itu, itu baik untuk diketahui.
Janis
2

Alih-alih mengandalkan nama file untuk membersihkan file cadangan Anda, Anda akan lebih aman mengandalkan metadata waktu mereka.

Misalnya Anda dapat menghapus semua file yang lebih lama dari 30 hari dengan perintah ini:

/usr/bin/find /path/to/your/files -type f -ctime +30 -delete

Sebagai bonus gratis, menjalankan ini setiap hari akan memungkinkan Anda untuk menyimpan file cadangan pada bulan bergulir, memungkinkan manajemen ruang disk yang lebih baik.

Untuk menyimpan file ke-1 atau ke-15, Anda bisa menyimpannya di direktori lain, perbarui perintah temukan dengan opsi -not -name.

Bertrand Lupart
sumber
0

Anda dapat mencoba melihat bagaimana tanggal bekerja dengan yang berikut:

date -d "$(date -d "Mar 31 2019" +%F) +1 month ago"
Sun Mar  3 00:00:00 EET 2019

Jadi saya pikir berdasarkan pada curent bulan lalu (bukan curent, kalau itu Maret), mengurangi jumlah hari dari bulan terakhir dari bulan curent.

Anda dapat mencoba sintaks berikut untuk menghapus file yang lebih lama dari beberapa hari (dalam contoh di bawah 31 hari). Satu baris untuk menyelesaikan masalah (ini untuk pendekatan sederhana).

find /path/to/folder/with/arhives/ -mindepth 1 -mtime +31 -delete

Untuk pendekatan yang lebih rinci, Anda juga dapat melakukan sesuatu seperti ini: 1. Menemukan jumlah hari untuk bulan terakhir:

cal $(date +%m) $(date +%y) | egrep -v "$(date +%y)|Su" | xargs | awk '{print $NF}'
  1. Menemukan jumlah hari untuk bulan terakhir:

    echo "$ (cal $ (tanggal +% m) $ (tanggal +% y) | egrep -v" $ (tanggal +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (tanggal -d "+1 bulan lalu" +% m) $ (tanggal +% y) | egrep -v "$ (tanggal +% y) | Su" | xargs | awk '{print $ NF}') | bc

  2. Jadi sekarang kita menemukan perbedaan antara dua bulan itu:

    echo "$ (cal $ (tanggal +% m) $ (tanggal +% y) | egrep -v" $ (tanggal +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (tanggal -d "+1 bulan lalu" +% m) $ (tanggal +% y) | egrep -v "$ (tanggal +% y) | Su" | xargs | awk '{print $ NF}') | bc

Sekarang mari kita tetapkan beberapa variabel ke 3 langkah ini. Langkah 1 Nama Variabel: FCM Langkah 2 Nama Variabel: FLM Langkah 3 Variabel NAme: DCL

FCM=$(cal $(date +%m) $(date +%y) | egrep -v "$(date +%y)|Su" | xargs | awk '{print $NF}')
FLM=$(al $(date -d "+1 month ago" +%m) $(date +%y) | egrep -v "$(date +%y)|Su" | xargs | awk '{print $NF}')
DCL=$(echo "$FCM-$FLM" | bc)

Verifikasi apakah $ DCL sama dengan 0 (nol) dan hapus berdasarkan perbedaan antara $ FCM dan $ FLM:

if [ $DCL -ne 0 ]; then
    if [ $DCL -lt 0 ]; then
        find /path/to/folder/with/arhives/ -mindepth 1 -mtime +$(echo "$DCL+$FLM" | bc) -delete
    elif [ $DCL -gt 0 ]; then
        find /path/to/folder/with/arhives/ -mindepth 1 -mtime +$(echo "$DCL+$FLM" | bc) -delete
    fi
else
    find /path/to/folder/with/arhives/ -mindepth 1 -mtime +$FLM -delete
fi

Anda juga dapat menambahkan variabel ke "/ path / ke / folde / with / arhives /".

Kesimpulan: Jika Anda ingin menghapus file yang lebih lama dari satu bulan (tepatnya), Anda perlu menyesuaikan jumlah hari yang tepat, jika Anda menggunakan perintah "date" dan "+1 month ago".

Mihai M
sumber