Làm thế nào để tùy chọn 1 tháng trước của Tùy chọn trong lệnh ngày hoạt động?


22

Tôi không chắc chắn nếu điều này có được ngày quá khứ trong ngày hiện tại hoặc nếu nó chỉ mất 30 hoặc 31 ngày cho nó.

ví dụ

Nếu ngày hiện tại là March 28th, 1 tháng trước phải có February 28th, nhưng điều gì xảy ra khi đó là March 30th?

Kịch bản

Tôi muốn sao lưu một số tệp mỗi ngày, tập lệnh sẽ lưu các tệp này trong ngày hiện tại với $(date +%Y%m%d)định dạng, như 20150603_bckp.tar.gzsau đó, khi tháng tiếp theo đến, hãy xóa tất cả các tệp đó trong vòng 1 tháng trước ngoại trừ các tệp thứ 1 và 15, vì vậy đây là điều kiện của tôi:

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

Nhưng tôi muốn biết, điều gì sẽ xảy ra khi ngày 30, 31 hoặc thậm chí là ví dụ tháng hai vừa qua? Nó sẽ giữ những tập tin đó? hoặc loại bỏ các tập tin ngày 1?

Khi đó là ngày 31, việc hủy bỏ sẽ thực thi, vì vậy nếu tháng trước chỉ có 30 ngày, điều này sẽ xóa ngày thứ 1?

Tôi hy vọng tôi gợi ý.


1
Bạn sẽ không biết tôi ở đây vào ngày 30 tháng 3 vì lý do chính xác này
user7203

Câu trả lời:


24

- 1 monthsẽ trừ đi một số từ số tháng và sau đó nếu ngày kết quả không hợp lệ ( February 30ví dụ), hãy điều chỉnh nó sao cho hợp lệ. Vì vậy, December 31 - 1 monthDecember 1, không phải là một ngày trong tháng Mười Một, và March 31 - 1 monthMarch 3(trừ trường hợp thực hiện trong một năm nhuận).

Dưới đây là trích dẫn từ trang thông tin cho Gnu date(là datephiên bản thực hiện cú pháp này), bao gồm một gợi ý hay để làm cho số học mạnh mẽ hơn:

Các fuzz trong các đơn vị có thể gây ra vấn đề với các mục tương đối. Ví dụ: 2003-07-31 -1 monthcó thể đánh giá đến 2003-07-01, vì 2003-06-31 là một ngày không hợp lệ. Để xác định tháng trước đáng tin cậy hơn, bạn có thể yêu cầu tháng trước ngày 15 của tháng hiện tại. Ví dụ:

    $ 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!

Một cảnh báo khác, cũng được trích dẫn từ trang thông tin:

Ngoài ra, hãy cẩn thận khi thao tác ngày xung quanh thay đổi đồng hồ, chẳng hạn như bước nhảy tiết kiệm ánh sáng ban ngày. Trong một vài trường hợp, những thứ này đã cộng hoặc trừ tối đa 24 giờ so với đồng hồ, do đó, nên áp dụng thời gian phổ quát bằng cách đặt TZbiến môi trường thành UTC0 trước khi bắt đầu tính toán theo lịch.


Tôi có một nghi ngờ ở đây, cụ thể là trong tình huống tháng hai ... Khi đó là ngày 29, 30 hoặc 31 tháng 3, nó có thể lấy số sau của tháng trước nếu hiện tại không tồn tại, vì vậy trong ba tình huống này có thể xảy ra Ngày 1 tháng 3 không? Nguyên nhân là nếu ngày 29, 30, 31 và sau đó là 1 tháng 3, 2, 3 như bạn đã nói, thì ngày 1 tháng 4 sẽ là ngày 4 tháng 3 do việc tái cấu trúc (tôi không biết nếu nó được nói rõ), bạn nghĩ sao? ?
tachomi

Một tháng trước ngày 1 tháng 4 là ngày 1 tháng 3 và một tháng trước ngày 1 tháng 3 là ngày 1 tháng 2 Đây không phải là vấn đề. Vấn đề là một tháng trước ngày 31 tháng 5 là ngày 1 tháng 5 vì ngày 31 tháng 4 không tồn tại. Bạn nên kiểm tra số ngày của ngày một tháng trước, không phải ngày của ngày hiện tại.
ngày

2
Đừng! Việc "một tháng trước" của một số ngày cụ thể trong bất kỳ tháng nào có thể dẫn đến cùng một tháng là điều tôi không mong đợi từ dateviệc triển khai; trong cuốn sách của tôi, nó là phản trực giác. - Cảm ơn đã chỉ ra rằng, thật tốt khi biết.
Janis

2

Thay vì dựa vào tên tệp để xóa các tệp sao lưu của bạn, bạn sẽ an toàn hơn khi dựa vào siêu dữ liệu thời gian của chúng.

Ví dụ: bạn có thể xóa tất cả các tệp cũ hơn 30 ngày bằng lệnh này:

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

Là một phần thưởng miễn phí, việc chạy này hàng ngày sẽ cho phép bạn giữ các tệp sao lưu của mình trong một tháng, cho phép quản lý không gian đĩa tốt hơn.

Để giữ các tệp thứ 1 hoặc thứ 15, bạn có thể lưu trữ chúng trong thư mục khác, cập nhật lệnh find với tùy chọn -not -name.


0

Bạn có thể thử xem ngày hoạt động như thế nào sau đây:

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

Vì vậy, tôi nghĩ rằng dựa trên tháng trước (không phải là tháng ba), nếu đó là tháng ba), sẽ giảm số ngày từ tháng trước so với tháng trước.

Bạn có thể thử cú pháp sau để xóa các tệp cũ hơn sau đó một số ngày (trong ví dụ dưới 31 ngày). Một dòng để giải quyết vấn đề (đây là một cách tiếp cận đơn giản).

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

Để có cách tiếp cận chi tiết hơn, bạn cũng có thể làm một cái gì đó như thế này: 1. Tìm số ngày cho tháng hiện tại:

cal $(date +%m) $(date +%y) | egrep -v "$(date +%y)|Su" | xargs | awk '{print $NF}'
  1. Tìm số ngày trong tháng trước:

    echo "$ (cal $ (ngày +% m) $ (ngày +% y) | egrep -v" $ (ngày +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (ngày -d "+1 tháng trước" +% m) $ (ngày +% y) | egrep -v "$ (ngày +% y) | Su" | xargs | awk '{print $ NF}') | bc

  2. Vì vậy, bây giờ chúng tôi tìm thấy sự khác biệt giữa hai tháng đó:

    echo "$ (cal $ (ngày +% m) $ (ngày +% y) | egrep -v" $ (ngày +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (ngày -d "+1 tháng trước" +% m) $ (ngày +% y) | egrep -v "$ (ngày +% y) | Su" | xargs | awk '{print $ NF}') | bc

Bây giờ hãy gán một số biến cho 3 bước này. Bước 1 Tên biến: FCM Bước 2 Tên biến: FLM Bước 3 Biến 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)

Xác minh xem $ DCL bằng 0 (không) và xóa dựa trên chênh lệch giữa $ FCM và $ 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

Bạn cũng có thể thêm một biến vào "/ path / to / Folde / with / arhives /".

Kết luận: Nếu bạn muốn xóa các tệp cũ hơn một tháng (chính xác), bạn cần điều chỉnh số ngày chính xác, nếu bạn đang sử dụng lệnh "ngày" và "+1 tháng trước".

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.