วิธีเพิ่มวันที่ในไฟล์สำรอง


69

ฉันต้องการสำรองไฟล์และฉันต้องการให้มีการประทับเวลาเป็นส่วนหนึ่งของชื่อเพื่อให้แยกความแตกต่างได้ง่ายขึ้น

คุณจะฉีดวันที่ปัจจุบันลงในคำสั่ง copy ได้อย่างไร

[root@mongo-test3 ~]# cp foo.txt {,.backup.`date`}
cp: target `2013}' is not a directory

[root@mongo-test3 ~]# cp foo.txt {,.backup. $((date)) }
cp: target `}' is not a directory  

[root@mongo-test3 ~]# cp foo.txt foo.backup.`date`
cp: target `2013' is not a directory

คำตอบ:


108

สิ่งนี้ไม่ทำงานเนื่องจากคำสั่งdateส่งคืนสตริงที่มีช่องว่าง

$ date
Wed Oct 16 19:20:51 EDT 2013

หากคุณต้องการชื่อไฟล์อย่างนั้นคุณจะต้องล้อมสตริงนั้นด้วยเครื่องหมายคำพูด

$ touch "foo.backup.$(date)"

$ ll foo*
-rw-rw-r-- 1 saml saml 0 Oct 16 19:22 foo.backup.Wed Oct 16 19:22:29 EDT 2013

คุณอาจจะนึกถึงสายอักขระที่แตกต่างกันที่จะผนวกเข้าด้วยกัน ฉันมักจะใช้สิ่งนี้:

$ touch "foo.backup.$(date +%F_%R)"
$ ll foo*
-rw-rw-r-- 1 saml saml 0 Oct 16 19:25 foo.backup.2013-10-16_19:25

ดูหน้า man สำหรับวันที่สำหรับรหัสการจัดรูปแบบเพิ่มเติมรอบผลลัพธ์สำหรับวันที่ & เวลา

รูปแบบเพิ่มเติม

หากคุณต้องการควบคุมอย่างเต็มที่หากคุณปรึกษาหน้า man คุณสามารถทำสิ่งนี้:

$ date +"%Y%m%d"
20131016

$ date +"%Y-%m-%d"
2013-10-16

$ date +"%Y%m%d_%H%M%S"
20131016_193655

+1 - ฉันใช้ตัวระบุรูปแบบสำหรับวันที่เสมอไม่ว่าจะเป็น "% Y% m% d-% H% M% S" หรือ "% y% m% d%% d-% H% M% S"
ChuckCottrill

เพียงแค่ใช้touch foo`date +%F`งานได้ดี
Vadzim

ข้อแม้: สิ่งนี้ใช้ไม่ได้ในcshเชลล์
Govinda Sakhare

1
@GovindaSakhare - csh / tcsh สลับสัญกรณ์ subshell เพื่อ backticks ( ...) $(..)แทน ดูเหมือนว่า C shells ไม่รองรับสัญกรณ์นั้นสำหรับ subshells
slm

13
cp foo.txt {,.backup.`date`}

cp foo.txt .backup.Thu Oct 17 01:02:03 GMT 2013นี้จะขยายไปยังสิ่งที่ต้องการ ช่องว่างก่อนที่เครื่องมือจัดฟันจะเริ่มคำใหม่

cp foo.txt {,.backup. $((date)) }

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

cp foo.txt foo.backup.`date`

ใกล้ชิด cp foo.{txt,.backup.`date`}คุณอาจจะได้แสดงนี้กับการจัดฟันเป็น ยังคงมีปัญหาที่เอาต์พุตของdateมีช่องว่างดังนั้นจึงต้องใส่เครื่องหมายคำพูดคู่ สิ่งนี้จะได้ผล:

cp foo.{txt,backup."`date`"}

หรือ

cp foo.{txt,backup."$(date)"}

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

cp foo.{txt,backup."$(date +%Y%m%d-%H%M%S)"}

อันสุดท้ายให้ฉัน cp: target `foo..backup.20160913-134158 'ไม่ใช่ไดเรกทอรี
Kalpesh Soni

@KalpeshSoni คำสั่งที่แน่นอนที่ฉันโพสต์ไม่สามารถสร้างข้อความแสดงข้อผิดพลาดนี้ได้ คุณต้องใช้คำสั่งอื่น
Gilles

10

หากคุณต้องการใช้วันที่อย่างละเอียดคุณควรปกป้อง backtick รูปแบบวันที่นี้คือมันมีช่องว่างฝังอยู่, no-no ใน Unix shell ยกเว้นว่าคุณใส่ไว้ในเครื่องหมายคำพูด (หรือหลีกเลี่ยงวิธีอื่น)

cp foo.txt "foo-`date`.txt"

อย่างไรก็ตามฉันต้องการใช้รูปแบบ ISO ที่สั้นกว่า:

cp foo.txt foo-`date --iso`.txt

5

ใช้ฟังก์ชั่นมันจะทำให้ชีวิตของคุณง่ายขึ้น นี่คือสิ่งที่ฉันใช้:

backup () { 
    for file in "$@"; do
        local new=${file}.$(date '+%Y%m%d')
        while [[ -f $new ]]; do
            new+="~";
        done;
        printf "copying '%s' to '%s'\n" "$file" "$new";
        \cp -ip "$file" "$new";
    done
}

4

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

นี่เป็นวิธีแก้ปัญหาที่เป็นไปได้โดยไม่มีช่องว่าง:

cp foo.txt foo.backup.$(date --iso-8601=seconds)  

หรือ

cp foo.txt foo.backup.`date --iso-8601=seconds`

ถ้าคุณเพิ่ม

bk() {
     cp -a "$1" "${1}_$(date --iso-8601=seconds)"
}

ที่คุณ.bashrcและใหม่เข้าสู่ระบบ / bk file.txtให้ทุบตีคุณอ่านมันคุณจะต้องเพียงเพื่อเรียก


คู่มือวันที่ RHEL ของฉันไม่แสดง--iso-8601สวิตช์ดังนั้นฉันจึงใส่ลิงค์ที่นี่ ตัวเลือกวันที่ของ GNU: --iso-8601
Ivan Chau

3

คุณคัดลอกไฟล์ไปยังไฟล์สำรองที่สร้างชื่อด้วยการประทับเวลาต่อท้าย

cp foo.txt backup_`date +"%d-%m-%Y"`.txt

หรือ:

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

cat foo.txt > backup_`date +"%d-%m-%Y"`.txt

นอกจากนี้คุณยังสามารถใช้ตัวเลือกการควบคุม FORMAT เพิ่มเติมตามความต้องการของคุณเช่น:% H,% M,% S, ฯลฯ


ประโยชน์ของการcatเปลี่ยนเส้นทางมากกว่าcpคืออะไร
Guido

มันเป็นเพียงวิธีอื่นในการทำเช่นนั้น
Atul Rokade

1

ในทุบตีคุณสามารถพิมพ์:

cp /path/to/long/filename !#$_$(date +Is)

ซึ่งขยายเป็น:

cp /path/to/long/filename /path/to/long/filename_$(date +Is)

ที่เกิดขึ้นใน:

$ ls /path/to/long/filename*
filename  filename_2017-05-10T11:50:10+0300

date -Isที่ถูกเนื้อ ฉันชอบที่จะใช้เพราะจำง่ายพิมพ์และอนุญาตเวอร์ชันสั้น ๆ (เช่น-Inถ้าคุณเป็นคนที่คลั่งไคล้แม่นยำ)


! เริ่มตัวออกแบบเหตุการณ์:

 !#     The entire command line typed so far.

และ$เป็นตัวกำหนดคำ:

   $      The last word.  This is usually the last argument, but will expand to the zeroth word if there is only one word in the line.

1

เมื่อฉันต้องสำรองไฟล์ฉันมักจะทำเช่นนี้

cp foo.txt foo.backup.$(date +%F).txt

ls -l

foo.txt foo.backup.2017-9-19.txt


1
นี่ไม่ได้เพิ่มอะไรที่คำตอบอื่น ๆ ยังไม่ได้นำเสนอ นอกจากนี้%Fรูปแบบวันที่สร้างเดือน 2 หลักและls -lมักจะให้ข้อมูลมากกว่าชื่อไฟล์เพียงเล็กน้อย
Kusalananda

0

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

กล่าวคือ

cp filename.sh{,."`date`"}

ซึ่งส่งผลให้

filename.sh.Sun 29 Sep 00:44:43 BST 2019

หรือเพียงใช้

cp filename{,.20190929}

filename.sh.20190929

ผนวกวันที่เพื่อตอบสนองความต้องการของคุณ :)

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