ฉันจะหยุดสร้างสิ่งที่ซ้ำกันได้ไหม


13

หากฉันรัน wget สองครั้งก็ไม่รู้จักว่ามันดาวน์โหลดไฟล์นั้นไปแล้วและสร้างไฟล์ใหม่ มีวิธีป้องกันการดาวน์โหลดไฟล์อีกครั้งหรือไม่?

$ wget https://cdn.sstatic.net/askubuntu/img/logo.png
...
Saving to: ‘logo.png’
...

$ wget https://cdn.sstatic.net/askubuntu/img/logo.png
...
Saving to: ‘logo.png.1’
...

(ยินดีที่จะใช้ curl หรือทางเลือกสคริปต์ที่คล้ายกันหาก wget ไม่สามารถทำได้)


9
มันสร้างไฟล์ใหม่ขึ้นมาเพราะมันจำไฟล์ได้แล้ว!
โก้

คำตอบ:


17

ฉันแนะนำให้คุณใช้-Nตัวเลือก

-N
--timestamping
    Turn on time-stamping.

มันเปิดใช้งานการลงเวลาซึ่งจะดาวน์โหลดไฟล์ใหม่เฉพาะเมื่อไฟล์นั้นใหม่กว่าบนเซิร์ฟเวอร์มากกว่าเวอร์ชั่นที่ดาวน์โหลดมา

$ wget -N https://cdn.sstatic.net/askubuntu/img/logo.png
...
Saving to: ‘logo.png’
...

$ wget -N https://cdn.sstatic.net/askubuntu/img/logo.png
...
Server file no newer than local file ‘logo.png’ -- not retrieving.

Caveat (จากความคิดเห็นของ KasiyA)

หากเซิร์ฟเวอร์ไม่ได้รับการกำหนดค่าอย่างถูกต้องอาจรายงานว่าไฟล์นั้นเป็นไฟล์ใหม่-Nเสมอและจะทำการดาวน์โหลดไฟล์อีกครั้ง ในกรณี-ncนี้อาจเป็นตัวเลือกที่ดีกว่า


3
เมื่อเซิร์ฟเวอร์ไม่ได้รับการกำหนดค่าอย่างเหมาะสม-Nอาจล้มเหลวและ wget จะทำการดาวน์โหลดซ้ำเสมอ ดังนั้นบางครั้ง-ncจะดีกว่า-N
αғsнιη

1
@Kasiy ขอบคุณสำหรับความคิดเห็นของคุณดูเหมือนจะไม่มีตัวเลือกที่ดีสำหรับทุกกรณี
กรกฎาคม

16

ใช่มันเป็น-cตัวเลือก

--continue
    Continue getting a partially-downloaded file.  This is useful when you want to
    finish up a download started by a previous instance of Wget, or by another
    program.

หากไฟล์เหมือนกันความพยายามในการดาวน์โหลดครั้งที่สองจะหยุด

$ wget -c https://cdn.sstatic.net/askubuntu/img/logo.png
...
Saving to: ‘logo.png’
...

$ wget -c https://cdn.sstatic.net/askubuntu/img/logo.png
...
The file is already fully retrieved; nothing to do.

Caveats (จากความคิดเห็นของ jofel)

หากไฟล์มีการเปลี่ยนแปลงบนเซิร์ฟเวอร์-cตัวเลือกสามารถให้ผลลัพธ์ที่ไม่ถูกต้อง

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


การทดสอบในท้องถิ่น

คุณสามารถทดสอบได้โดยใช้เว็บเซิร์ฟเวอร์ในพื้นที่แบบง่าย ๆ ดังต่อไปนี้ (ขอบคุณคำตอบของ@roadmr ):

เปิดหน้าต่างเทอร์มินัลแล้วพิมพ์:

cd /path/to/parent-download-dir/
python -m SimpleHTTPServer

ตอนนี้เปิดเทอร์มินัลอื่นและทำ:

wget -c http://localhost:8000/filename-to-download

โปรดทราบว่าfilename-to-downloadเป็นไฟล์ที่/path/to/parent-download-dir/เราต้องการดาวน์โหลด

ตอนนี้ถ้าคุณรันคำสั่ง wget หลายครั้งคุณจะเห็น:

The file is already fully retrieved; nothing to do.

ตกลงตอนนี้ไปที่/path/to/parent-download-dir/ไดเรกทอรีและเพิ่มบางสิ่งบางอย่างลงในไฟล์ต้นฉบับตัวอย่างเช่นถ้าเป็นไฟล์ข้อความให้เพิ่มบรรทัดพิเศษอย่างง่ายในไฟล์นั้นและบันทึกไฟล์ wget -c ...ตอนนี้ลองกับ เยี่ยมมากตอนนี้คุณจะเห็นไฟล์ดาวน์โหลดอีกครั้ง แต่คุณเคยดาวน์โหลดมาก่อนแล้ว

เหตุผล: ทำไมต้องดาวน์โหลดซ้ำ

เพราะขนาดของมันเปลี่ยนเป็นขนาดใหญ่กว่าไฟล์ที่ดาวน์โหลดมาเก่าและไม่มีอะไรอื่น


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

1
@ jofel ใช่-ncไม่ได้อย่างที่คุณพูด แต่-cตัวเลือกจะทำงานและนั่นคือเหตุผลที่ฉันพูดถึง-cตัวเลือกแรก
αғsнιη

ด้วย-c, wgetถามเซิร์ฟเวอร์สำหรับข้อมูลใด ๆ ที่นอกเหนือจากส่วนหนึ่งของไฟล์ที่ดาวน์โหลดมาแล้วไม่มีอะไรอื่น จะไม่ตรวจสอบว่ามีการเปลี่ยนแปลงในส่วนที่ดาวน์โหลดแล้วของไฟล์บนเซิร์ฟเวอร์หรือไม่ ที่แย่ที่สุดคุณจะได้รับไฟล์ที่เสียหายซึ่งเป็นการผสมผสานระหว่างไฟล์เก่ากับไฟล์ใหม่
jofel

หลังจากตรวจสอบตัวเลือกแล้วฉันคิดว่านี่เป็นประโยชน์สำหรับบางอย่างเช่นล็อกไฟล์ (รับประกันอัปเดตที่เพิ่มขึ้น) ในกรณีอื่น ๆ ทั้งหมดฉันคิดว่า -N หรือ -nc เหมาะสมกว่าเนื่องจากจัดการกับไฟล์ทั้งหมด
david.libremone

3

นอกจากนี้ยังมีตัวเลือกอื่นที่เรียกว่า-ncสำหรับ wgetting:

--no-clobber
   If a file is downloaded more than once in the same directory, Wget's behavior
   depends on a few options, including -nc.  In certain cases, the local file will
   be clobbered, or overwritten, upon repeated download.  In other cases it will be
   preserved.

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

$ wget -nc https://cdn.sstatic.net/askubuntu/img/logo.png
...
Saving to: ‘logo.png’
...

$ wget -nc https://cdn.sstatic.net/askubuntu/img/logo.png
File ‘logo.png’ already there; not retrieving.

บางครั้งตัวเลือกนี้ดีมากและฉันแนะนำให้ใช้-ncตัวเลือกแทนทั้งคู่-cหรือ-Nตัวเลือกเพราะตัวเลือกเหล่านี้จะเขียนทับไฟล์ดาวน์โหลดด้วยไฟล์ในเครื่องของคุณหากมีชื่อเหมือนกัน

Caveat (จากความคิดเห็นของ jofel)

-ncตัวเลือกไม่ได้อัปเดตไฟล์ถ้ามันมีการเปลี่ยนแปลงบนเซิร์ฟเวอร์ หากคุณรู้ว่าไฟล์จะเปลี่ยนแปลง-Nตัวเลือกจะดีกว่า หากคุณรู้ว่าไฟล์จะไม่เปลี่ยนแปลง (หรือคุณไม่สนใจ) ก็-ncโอเค


1

ฉันรู้ว่านี่เป็นคำถามเฉพาะเกี่ยวกับ wget แต่ OP ได้พูดถึง "ยินดีที่จะใช้ curl หรือทางเลือกสคริปต์ที่คล้ายกันถ้า wget ไม่สามารถทำได้" ฉันไม่แน่ใจว่าสิ่งที่ต้องการคืออะไร (หลายไฟล์เก็บเวอร์ชันเก่าหากแตกต่างจากต้นฉบับแทนที่ด้วยเวอร์ชันที่ดาวน์โหลดใหม่) ขึ้นอยู่กับสิ่งที่คุณต้องการและวิธีที่คุณต้องการจัดการสิ่งที่ซ้ำกันคุณอาจต้องการมากกว่านี้ .. วิธีที่ง่ายที่สุดในการทำสิ่งที่คุณต้องการคือการใช้ขดแทน

curl http://cdn.sstatic.net/askubuntu/img/logo.png?v=ca4d192163aa > logo.png

คำสั่งนี้จะแทนที่ไฟล์เก่าด้วยไฟล์ที่ดาวน์โหลดใหม่ทุกครั้ง

อย่าส่งเอาต์พุตนี้ไปยังเทอร์มินัล (โดยไม่มี "> [filename]") หากคุณกำลังดาวน์โหลดไฟล์ไบนารีซึ่งตรงข้ามกับข้อความ การทำเช่นนั้นอาจจะยุ่งกับเซสชันเทอร์มินัลของคุณ ในกรณีที่คุณทำโดยบังเอิญคุณอาจต้องเปิดเซสชันเชลล์ / เทอร์มินัลอีกครั้ง


หากเทอร์มินัลของคุณมีรูปร่างไม่ดีเนื่องจากคุณแสดงไฟล์ไบนารีอาจเป็นการง่ายกว่าที่จะเรียกโปรแกรม "รีเซ็ต" มากกว่าการเปิดเทอร์มินัลใหม่
กรกฎาคม

คุณพูดถูกที่ฉันไม่ชัดเจนเกี่ยวกับความต้องการของฉันผลลัพธ์ที่ได้คือความสุขที่ฉันได้เรียนรู้เกี่ยวกับตัวเลือกเพิ่มเติมอีกสองสามข้อ :) ขอบคุณ
david.libremone

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