ตัวเลือก“ 1 เดือนที่ผ่านมา” ในคำสั่ง date ทำงานอย่างไร


22

ฉันไม่แน่ใจว่าจะได้รับวันที่ผ่านมาภายในวันที่ปัจจุบันหรือถ้าใช้เวลาเพียง 30 หรือ 31 วัน

เช่น

หากวันที่ปัจจุบันคือMarch 28th1 เดือนที่ผ่านมาจะต้องเป็นFebruary 28thแต่จะเกิดอะไรขึ้นเมื่อมันMarch 30th?

สถานการณ์

ฉันต้องการสำรองข้อมูลบางไฟล์ในแต่ละวันสคริปต์จะบันทึกไฟล์นี้ภายในวันที่ปัจจุบันด้วย$(date +%Y%m%d)รูปแบบเช่น20150603_bckp.tar.gzจากนั้นเมื่อถึงเดือนถัดไปให้ลบไฟล์เหล่านั้นทั้งหมดภายใน 1 เดือนที่ผ่านมายกเว้นไฟล์ที่ 1 และ 15 ดังนั้นนี่คือ สภาพของฉัน:

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

แต่ฉันอยากรู้ว่าจะเกิดอะไรขึ้นเมื่อวันที่ 30, 31 หรือตัวอย่างเดือนกุมภาพันธ์ที่ผ่านมา? มันจะเก็บไฟล์เหล่านั้นเหรอ? หรือลบไฟล์วันที่ 1?

เมื่อเป็นวันที่ 31 ของการถอดถอนจะดำเนินการดังนั้นหากเดือนที่ผ่านมามีเพียง 30 วันไฟล์นี้จะลบไฟล์วันที่ 1 หรือไม่

ฉันหวังว่าฉันพูดเป็นนัย


1
คุณจะไม่ทราบหรือไม่ว่าฉันมาที่นี่ในวันที่ 30 มีนาคมด้วยเหตุผลที่แน่นอนนี้
user7203

คำตอบ:


24

- 1 monthจะลบหนึ่งหมายเลขจากเดือนและจากนั้นหากวันที่เกิดไม่ถูกต้อง ( February 30เช่น) ให้ปรับวันที่นั้นให้ถูกต้อง ดังนั้นDecember 31 - 1 monthเป็นDecember 1ไม่วันในเดือนพฤศจิกายนและMarch 31 - 1 monthเป็นMarch 3(ยกเว้นกรณีที่ดำเนินการในปีอธิกสุรทิน)

นี่คือคำพูดจากหน้าข้อมูลสำหรับ Gnu date(ซึ่งเป็นdateรุ่นที่ใช้ไวยากรณ์นี้) ซึ่งรวมถึงข้อเสนอแนะที่ดีในการทำให้การคำนวณทางคณิตศาสตร์มีประสิทธิภาพยิ่งขึ้น:

fuzz ในหน่วยสามารถทำให้เกิดปัญหากับรายการที่เกี่ยวข้อง ตัวอย่างเช่น2003-07-31 -1 monthอาจประเมินเป็น 2003-07-01 เนื่องจาก 2003-06-31 เป็นวันที่ไม่ถูกต้อง หากต้องการตรวจสอบเดือนก่อนหน้าอย่างน่าเชื่อถือมากขึ้นคุณสามารถขอเดือนก่อนวันที่ 15 ของเดือนปัจจุบัน ตัวอย่างเช่น:

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

คำเตือนอื่นอ้างถึงจากหน้าข้อมูล:

นอกจากนี้โปรดระมัดระวังเมื่อจัดการกับวันที่ที่มีการเปลี่ยนแปลงนาฬิกาเช่น leaps การปรับเวลาตามฤดูกาล ในบางกรณีเหล่านี้ได้เพิ่มหรือลบมากถึง 24 ชั่วโมงจากนาฬิกาดังนั้นจึงมักจะฉลาดที่จะใช้เวลาสากลโดยการตั้งค่าTZตัวแปรสภาพแวดล้อมUTC0 ก่อนที่จะเริ่มดำเนินการคำนวณปฏิทิน


ฉันมีข้อสงสัยในที่นี่โดยเฉพาะในสถานการณ์เดือนกุมภาพันธ์ ... เมื่อวันที่ 29 มีนาคม 30 หรือ 31 อาจต้องใช้หมายเลขต่อไปนี้ของเดือนที่ผ่านมาหากไม่มีในปัจจุบันดังนั้นในสถานการณ์ทั้งสามนี้อาจจะใช้เวลา วันที่ 1 มีนาคม สาเหตุถ้าวันที่ 29, 30, 31 และวันที่ 1 มีนาคม 2, 3 ตามที่คุณพูดแล้ววันที่ 1 เมษายนจะเป็นวันที่ 4 มีนาคมเนื่องจากการปรับโครงสร้าง (ฉันไม่รู้ว่าพูดได้ดีหรือเปล่า) คุณคิดอย่างไร ?
tachomi

หนึ่งเดือนก่อนวันที่ 1 เมษายนคือ 1 มีนาคมและหนึ่งเดือนก่อน 1 มีนาคมคือ 1 กุมภาพันธ์สิ่งเหล่านี้ไม่ใช่ปัญหา ปัญหาคือว่าหนึ่งเดือนก่อนวันที่ 31 พฤษภาคมคือ 1 พฤษภาคมเนื่องจากไม่มีวันที่ 31 เมษายน คุณควรตรวจสอบหมายเลขวันของวันที่หนึ่งเดือนที่ผ่านมาไม่ใช่วันของวันที่ปัจจุบัน
rici

2
Doh! ความจริงที่ว่า "หนึ่งเดือนที่ผ่านมา" ของบางวันในเดือนใด ๆ อาจส่งผลให้ในเดือนเดียวกันคืออะไรที่ฉันคาดหวังจากการdateดำเนินการ; ในหนังสือของฉันมันตอบโต้ความหมายได้ง่าย - ขอบคุณสำหรับการชี้ให้เห็นว่ามันเป็นเรื่องดีที่จะรู้
Janis

2

แทนที่จะพึ่งพาชื่อไฟล์สำหรับการล้างไฟล์สำรองข้อมูลของคุณคุณจะปลอดภัยยิ่งขึ้นโดยใช้ข้อมูลเมตาของเวลา

ตัวอย่างเช่นคุณสามารถลบไฟล์ทั้งหมดที่เก่ากว่า 30 วันด้วยคำสั่งนี้:

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

ในฐานะโบนัสฟรีการใช้งานทุกวันจะช่วยให้คุณสามารถสำรองไฟล์ข้อมูลของคุณในเดือนที่ผ่านมาช่วยให้จัดการพื้นที่ดิสก์ได้ดีขึ้น

สำหรับการเก็บไฟล์ที่ 1 หรือ 15 คุณสามารถเก็บไว้ในไดเรกทอรีอื่นอัปเดตคำสั่ง find ด้วยตัวเลือก -not -name


0

คุณสามารถลองดูว่าวันที่ทำงานอย่างไรโดยทำสิ่งต่อไปนี้:

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

ดังนั้นฉันคิดว่าตามเดือนที่ผ่านมา (ไม่ใช่ curent หากเป็นมีนาคม) ลดจำนวนวันจากเดือนที่แล้วจากเดือนที่แล้ว

คุณสามารถลองใช้ไวยากรณ์ต่อไปนี้เพื่อลบไฟล์ที่เก่ากว่าแล้วใช้เวลาหลายวัน (ในตัวอย่างการร้อง 31 วัน) หนึ่งบรรทัดเพื่อแก้ปัญหา (นี่เป็นวิธีที่ง่าย)

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

สำหรับรายละเอียดเพิ่มเติมคุณสามารถทำสิ่งนี้ได้ดังนี้: 1. ค้นหาจำนวนวันสำหรับเดือนที่เข้าร่วม:

cal $(date +%m) $(date +%y) | egrep -v "$(date +%y)|Su" | xargs | awk '{print $NF}'
  1. การค้นหาจำนวนวันสำหรับเดือนที่ผ่านมา:

    echo "$ (cal $ (วันที่ +% m) $ (วันที่ +% y) | egrep -v" $ (วันที่ +% y) | Su "| xargs | awk '{พิมพ์ $ NF}') -" $ ( cal $ (วันที่ -d "+1 เดือนก่อน" +% m) $ (วันที่ +% y) | egrep -v "$ (วันที่ +% y) | Su" | xargs | awk '{พิมพ์ $ NF}') | ก่อนคริสต์ศักราช

  2. ดังนั้นตอนนี้เราพบความแตกต่างระหว่างสองเดือน:

    echo "$ (cal $ (วันที่ +% m) $ (วันที่ +% y) | egrep -v" $ (วันที่ +% y) | Su "| xargs | awk '{พิมพ์ $ NF}') -" $ ( cal $ (วันที่ -d "+1 เดือนก่อน" +% m) $ (วันที่ +% y) | egrep -v "$ (วันที่ +% y) | Su" | xargs | awk '{พิมพ์ $ NF}') | ก่อนคริสต์ศักราช

ตอนนี้ให้กำหนดตัวแปรบางอย่างให้ 3 ขั้นตอนนี้ ขั้นตอนที่ 1 ชื่อตัวแปร: FCM ขั้นตอนที่ 2 ชื่อตัวแปร: FLM ขั้นตอนที่ 3 ตัวแปร 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)

ตรวจสอบว่า $ DCL เท่ากับ 0 (ศูนย์) และลบตามความแตกต่างระหว่าง $ FCM และ $ 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

คุณยังสามารถเพิ่มตัวแปรใน "/ path / to / folde / with / arhives /"

สรุป: หากคุณต้องการลบไฟล์ที่เก่ากว่าหนึ่งเดือน (แน่นอน) คุณต้องปรับจำนวนวันที่แน่นอนหากคุณใช้คำสั่ง "date" และ "+1 เดือนที่ผ่านมา"

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.