Tag: date

  • date นั้นสำคัญไฉน

    ที่ Shell prompt พิมพ์คำสั่ง man date

    ได้อะไรมาไม่รู้เยอะแยะ…

    man date
    man date

    จากคู่มือจะเอารูปแบบวันที่ 12-09-2017 ตัวเลือกที่เกี่ยวข้องได้แก่ %d %D %e %F %g %G %m %y %Y เป็นต้น ลองส่งคำสั่ง

    date +"%d-%m-%Y"

    ได้ผลลัพธ์

    12-09-2017

    ตรงตามที่ต้องการ มาเขียนสคริปต์กันหน่อย อยากได้เมื่อวานทำไง วันนี้เล่น tcsh shell สร้างแฟ้ม date.tcsh ด้วย editor ที่ชื่นชอบมีข้อความว่า

    #!/bin/tcsh -f
    set tday=`date +"%d"`
    set tmonth=`date +"%m"`
    set tyear=`date +"%Y"`
    echo "Today is ${tday}-${tmonth}-${tyear}."
    set yday=`expr ${tday} - 1`
    echo "Yesterday was ${yday}-${tmonth}-${tyear}."

    ทดสอบสคริปต์ด้วยคำสั่ง

    tcsh date.tcsh

    ไม่อยากพิมพ์ tcsh ทุกครั้งเพิ่ม execution bit ด้วยคำสั่ง

    chmod +x date.tcsh

    เรียกใช้ได้โดยพิมพ์

    ./date.tcsh (อ่านว่า จุด-ทับ-เดต-จุด-ที-ซี-เอส-เอช)

    ผลลัพธ์ที่ได้

    Today is 12-09-2017.
    Yesterday was 11-09-2017.

    อยากได้เมื่อวานทำไมมันยากอย่างนี้ ฮา… ซึ่งเมื่อกลับไปอ่านคู่มือ (man date) ให้ดี..อีกครั้งจะพบว่ามีตัวเลือก

    -d, –date=STRING
    display time described by STRING, not ‘now’

    และเมื่่อเลื่อนลงมาล่างสุดจะพบว่า

    DATE STRING
    The –date=STRING is a mostly free format human readable date string such as “Sun, 29 Feb 2004 16:21:42 -0800” or
    “2004-02-29 16:21:42” or even “next Thursday”. A date string may contain items indicating calendar date, time of day,
    time zone, day of week, relative time, relative date, and numbers. An empty string indicates the beginning of the day.
    The date string format is more complex than is easily documented here but is fully described in the info documentation.

    โอ้ววว มันเขียนไว้หมดแล้ว…

    เขียนใหม่ได้ว่า
    date -d yesterday

    ได้ผลลัพธ์

    Mon Sep 11 21:43:51 +07 2017

    เปลี่ยนให้ผลลัพธ์ออกมาในรูปแบบที่ต้องการได้ด้วยคำสั่ง

    date -d yesterday +"%d-%m-%Y"

    ก็จะได้ผลลัพธ์ว่า

    11-09-2017

    แก้สคริปต์ date.tcsh

    #!/bin/tcsh -f
    set tday=`date -d today +"%d-%m-%Y"`
    set yday=`date -d yesterday +"%d-%m-%Y"`
    echo "Today is ${tday}."
    echo "Yesterday was ${yday}."

    เจ็บมาเท่าไหร่แล้วกับคำว่าไม่อ่านเอกสาร….

    ยังใส่ข้อความอื่นๆ แทน string ได้เช่น
    date -d 'tomorrow'
    date -d '-1 days ago'
    date -d '200 days'
    date -d '1000 weeks'
    date -d '30 months'
    date -d '300 years'

    เรื่องนี้สอนให้รู้ว่า บางทีเอกสารก็มีให้หมดแล้ว ไม่ต้องทำเองก็ด้ายยยยย….

    จบขอให้สนุก

    man date
    ค้นเพิ่มเติม https://www.cyberciti.biz/tips/linux-unix-get-yesterdays-tomorrows-date.html

  • Script สำหรับ หาวันที่ของไฟล์ล่าสุดใน directory

    Q: ถ้าจะเขียน คำสั่ง หรือ script บน linux เพื่อหา วันที่ของ file ล่าสุดใน folder ของ user จะเขียนยังไงดี มีไอเดียไหมครับ

    A: สมมติ folder ของ user คือ /home/user/Documents

    $ ls -t /home/user/Documents
    

    จะได้ไฟล์เรียงตามลำดับวันที่/เวลาของไฟล์ โดยไฟล์ล่าสุดจะโผล่มาเป็นไฟล์แรก

    ถ้าเราต้องการไฟล์ล่าสุดแค่ไฟล์เดียว ก็สามารถใช้คำสั่ง head -1 เพื่อตัดให้เหลือไฟล์เดียวได้ ก็จะได้คำสั่งเป็น

    $ ls -t /home/user/Documents | head -1
    

    ทีนี้ จากชื่อไฟล์ที่ได้ ถ้าต้องการวันที่ เราก็สามารถใช้คำสั่ง date โดยใช้ option -r สำหรับให้มันแสดงวันที่ของไฟล์ใดๆ ตย. เช่น ต้องการรู้วันที่ ของไฟล์ /etc/passwd ก็ใช้คำสั่ง

    $ date -r /etc/passwd
    

    เอาสองอย่างนี้มาใช้งานร่วมกันได้ตามนี้ครับ

    $ date -r `ls -t /home/user/Documents | head -1`
    

    ทีนี้ ถ้าต้องการให้ format ของวันที่ออกมาตามที่เราต้องการ อย่างเช่น ให้ format เป็น yyyy-mm-dd HH:MM:SS
    ก็เพิ่ม option ให้กับคำสั่ง date ประมาณนี้ “+%Y-%m-%d %H:%M:%S”

    รวมกันทั้งหมดเป็น

    $ date -r `ls -t /home/user/Documents | head -1` "+%Y-%m-%d %H:%M:%S"
    

    Q: ถ้าจะลงลึกไปหลาย level ต้องทำอะไรเพิ่มครับ
    A: หมายถึงต้องการไฟล์ล่าสุด ไฟล์เดียว จากใน directory นั้นและ sub directory ย่อยทั้งหมดใช่ใหมครับ?
    Q: ใช่ครับ
    A: งั้น คงต้องพึ่งพาคำสั่ง find ครับ เพื่อที่ list เอาเฉพาะไฟล์ทั้งหมดออกมาก่อน เพราะคำสั่ง ls ธรรมดามันจะไล่ไปตาม directory ทีละ directory

    เริ่มจาก

    $ find /home/user/Documents
    

    มันจะ list ทุกอย่างทั้งไฟล์ และ ไดเรคตอรี่และในไดเรคตอรี่ย่อยออกมา

    เราต้องการเฉพาะไฟล์ ระบุ option -type f
    เราต้องการให้มันแสดงวันที่ของไฟล์ออกมาด้วย อันนี้ต้องพึ่งคำสั่ง ls โดยใช้ option ของ ls เป็น –full-time

    $ find /home/user/Documents -type f -exec ls --full-time {} \;
    

    โดย {} เป็นการระบุว่าให้ find ใช้คำสั่ง ls –full-time กับ output ของ find ส่วน \; เป็นตัวระบุว่า จบ option ของ คำสั่ง find แค่นี้

    output ที่ได้ จะเป็นไฟล์ “ทั้งหมด” โดยที่ในแต่ละบรรทัดจะมี ข้อมูลอย่างอื่นของไฟล์นั้นออกมาด้วย เช่น permission, owner, group, size ซึ่งเราไม่สนใจ เราตัดเอาข้อมูลที่อยู่ข้างหน้าเหล่านั้นออกไปได้ โดยใช้คำสั่ง cut โดยในกรณีนี้ใช้ space ‘ ‘ เป็นตัวแบ่ง field และ เอาข้อมูลตั้งแต่ column ที่ 6 เป็นต้นไป

    $ find /home/user/Documents -type f -exec ls --full-time {} \; | cut -f6- -d' '
    

    คราวนี้เราก็ได้ไฟล์ทั้งหมดออกมาโดยนำหน้าชื่อไฟล์ด้วยวันที่/เวลา ซึ่งเราสามารถส่งเข้าไป sort โดยให้เรียงจากหลังมาหน้า
    sort -r และ เอา output ทั้งหมดมาตัดเอาเฉพาะบรรทัดแรกโดยใช้ คำสั่ง head -1 เหมือนเดิม

    $ find /home/user/Documents -type f -exec ls --full-time {} \; cut -f6- -d' ' | sort -r | head -1
    

    ซึ่ง output ที่ได้จากคำสั่ง head อันนี้จะมี วัน/เวลาของไฟล์ นำหน้า ตามด้วยชื่อไฟล์ ซึ่งอาจจะเอาไปใช้งานได้เลย
    หรือ ถ้าต้องการเฉพาะชื่อไฟล์ เพื่อจะเอาไปทำอะไรอย่างอื่นต่อ ก็ต้องส่งไปให้คำสั่ง cut เพื่อตัด field ข้อมูลที่อยู่ด้านหน้าออก

    ขอบคุณคำถามจาก Garnet Komane ครับ

    ปล. สุดท้ายแล้วจากคำสั่งข้างบนที่ว่า แทนที่จะพิมพ์เอาบน command line แล้วไปเปลี่ยน path ที่จะให้ค้นหา เขียนมันใหม่เป็น shell script เลยจะเรียกใช้งานได้ง่ายกว่า ซึ่งจะได้ shell script ประมาณนี้ครับ

    #!/bin/bash
    
    LOCATION="$1"
    
    [ -z "$LOCATION" ] && { echo "Usage: $0 LOCATION"; exit; }
    
    FILE=$(
    find $LOCATION -type f -exec ls --full-time {} \;  |\
    cut -f6- -d' '                                     |\
    sort -r                                            |\
    head -1                                            |\
    cut -f4- -d' '
    )
    
    STAMP=$(date -r "$FILE" "+%Y-%m-%d %H:%M:%S")
    
    echo "$STAMP $FILE"
    

    หรือ ดาวน์โหลด script ได้จาก ที่นี่