วิธี rsync เฉพาะรายการไฟล์เฉพาะได้อย่างไร


95

ฉันมีไฟล์ประมาณ 50 ไฟล์หรือมากกว่านั้นในไดเรกทอรีย่อยต่างๆที่ฉันต้องการส่งไปยังเซิร์ฟเวอร์ระยะไกล ฉันคิดว่า rsync จะสามารถทำสิ่งนี้ให้ฉันได้โดยใช้ตัวเลือก --include-from หากไม่มีอ็อพชัน --exclude = "*" ไฟล์ทั้งหมดในไดเร็กทอรีจะถูกซิงค์โดยอ็อพชันจะไม่มีไฟล์ใด ๆ

rsync -avP -e ssh --include-from=deploy/rsync_include.txt --exclude=* ./ root@0.0.0.0:/var/www/ --dry-run

ฉันใช้งานแบบแห้งในตอนแรกและ 0.0.0.0 ถูกแทนที่ด้วย IP ของเซิร์ฟเวอร์ระยะไกลอย่างเห็นได้ชัด เนื้อหาของ rsync_include.txt เป็นรายการเส้นทางสัมพัทธ์ที่แยกจากบรรทัดใหม่ไปยังไฟล์ที่ฉันต้องการอัปโหลด

มีวิธีที่ดีกว่าในการทำสิ่งนี้ที่หนีฉันในเช้าวันจันทร์หรือไม่?

คำตอบ:


4

แก้ไข: คำตอบของ Josip Rodin ด้านล่างดีกว่า โปรดใช้อันนั้น!

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

# rsync -avP -e ssh `cat deploy/rsync_include.txt` root@0.0.0.0:/var/www/

อย่างไรก็ตามนี่เป็นการสมมติว่ารายการของคุณไม่ยาวมากจนความยาวบรรทัดคำสั่งจะเป็นปัญหาและrsync_include.txtไฟล์มีเพียงเส้นทางจริง (เช่นไม่มีความคิดเห็นและไม่มี regexps)


9
น่าเสียดายที่นี่ใช้ไม่ได้กับรายการขนาดใหญ่หรือไฟล์ที่มีช่องว่างในชื่อ
โหมด Wes

3
[รายการโต้แย้งยาวเกินไป]
DankóDávid

ตามค่าเริ่มต้น xargs จะต่อท้ายอาร์กิวเมนต์จาก stdin ไปที่ท้ายบรรทัดคำสั่ง ไม่ได้ผลเนื่องจาก rsync ต้องการอาร์กิวเมนต์สุดท้ายเพื่อเป็นปลายทาง xargs บางเวอร์ชันสามารถเลือกที่จะแทรกอาร์กิวเมนต์ไว้ตรงกลางของบรรทัดคำสั่งแทน สิ่งนี้ควรใช้งานได้ตราบเท่าที่คุณไม่ทราบว่าอาจเรียกใช้ rsync มากกว่าหนึ่งครั้งเมื่อรายการไฟล์มีความยาว ไม่ว่าในกรณีใดวิธีrsync --files-fromนี้น่าจะเป็นวิธีที่ง่ายและเชื่อถือได้มากกว่า :)
Lassi

Wes Hardaker: การแก้ไขและการอ้างอิง "คำตอบของ Josip Rodin" ของคุณอ้างถึงคำตอบของ @atpที่ Rodin แก้ไขจริงหรือไม่
Seamus

234

มีธง--files-fromที่ทำในสิ่งที่คุณต้องการ จากman rsync:

--files-from=FILE

การใช้ตัวเลือกนี้ช่วยให้คุณสามารถระบุรายการไฟล์ที่จะถ่ายโอนได้ (ตามที่อ่านจาก FILE ที่ระบุหรือ - สำหรับอินพุตมาตรฐาน) นอกจากนี้ยังปรับแต่งพฤติกรรมเริ่มต้นของ rsync เพื่อให้การถ่ายโอนไฟล์และไดเร็กทอรีที่ระบุง่ายขึ้น:

  • อ็อพชัน --relative (-R) เป็นนัยซึ่งจะเก็บรักษาข้อมูลพา ธ ที่ระบุไว้สำหรับแต่ละรายการในไฟล์ (ใช้ --no-relative หรือ --no-R หากคุณต้องการปิดใช้งาน)

  • โดยนัยอ็อพชัน --dirs (-d) ซึ่งจะสร้างไดเร็กทอรีที่ระบุไว้ในรายการบนปลายทางแทนที่จะข้ามไปอย่างเสียงดัง (ใช้ --no-dirs หรือ --no-d หากคุณต้องการปิด)

  • พฤติกรรมของอ็อพชัน --archive (-a) ไม่ได้หมายความถึง --recursive (-r) ดังนั้นให้ระบุอย่างชัดเจนหากคุณต้องการ

  • ผลข้างเคียงเหล่านี้เปลี่ยนสถานะเริ่มต้นของ rsync ดังนั้นตำแหน่งของตัวเลือก --files-from บนบรรทัดคำสั่งจึงไม่มีผลต่อวิธีการแยกวิเคราะห์ตัวเลือกอื่น ๆ (เช่น -a ทำงานเหมือนกันก่อนหรือหลัง --files- จากเช่นเดียวกับ --no-R และตัวเลือกอื่น ๆ ทั้งหมด)

ชื่อไฟล์ที่อ่านจาก FILE ทั้งหมดสัมพันธ์กับ dir ต้นทาง - เครื่องหมายทับนำหน้าใด ๆ จะถูกลบออกและไม่อนุญาตให้อ้างอิง ".. " สูงกว่า dir ต้นทาง ตัวอย่างเช่นใช้คำสั่งนี้:

rsync -a --files-from=/tmp/foo /usr remote:/backup

ถ้า / tmp / foo มีสตริง "bin" (หรือแม้แต่ "/ bin") ไดเร็กทอรี / usr / bin จะถูกสร้างเป็น / backup / bin บนรีโมตโฮสต์ หากมี "bin /" (สังเกตเครื่องหมายทับ) เนื้อหาในไดเร็กทอรีจะถูกส่งไปด้วย (โดยไม่จำเป็นต้องระบุอย่างชัดเจนในไฟล์ซึ่งเริ่มต้นในเวอร์ชัน 2.6.4) ในทั้งสองกรณีหากเปิดใช้งานอ็อพชัน -r ลำดับชั้นทั้งหมดของ dir นั้นก็จะถูกโอนไปด้วย (โปรดทราบว่า -r จำเป็นต้องระบุอย่างชัดเจนด้วย --files-from เนื่องจากไม่ได้แสดงโดยนัยโดย -a) นอกจากนี้โปรดทราบว่าเอฟเฟกต์ของตัวเลือก (เปิดใช้งานโดยค่าเริ่มต้น) --relative คือการทำซ้ำเฉพาะข้อมูลเส้นทางที่อ่านจากไฟล์ - ไม่บังคับให้มีการทำซ้ำของเส้นทางข้อมูลจำเพาะแหล่งที่มา (/ usr ในกรณีนี้) .

นอกจากนี้ไฟล์ --files-from ยังสามารถอ่านได้จากรีโมตโฮสต์แทนโลคัลโฮสต์หากคุณระบุ "โฮสต์:" ไว้ด้านหน้าไฟล์ (โฮสต์ต้องตรงกับปลายด้านหนึ่งของการถ่ายโอน) ในทางลัดคุณสามารถระบุเพียงคำนำหน้า ":" ถึงหมายถึง "ใช้การสิ้นสุดระยะไกลของการโอน" ตัวอย่างเช่น:

rsync -a --files-from=:/path/file-list src:/ /tmp/copy

การดำเนินการนี้จะคัดลอกไฟล์ทั้งหมดที่ระบุในไฟล์ / path / file-list ที่อยู่บนโฮสต์ "src" แบบรีโมต

หากระบุอ็อพชัน --iconv และ --protect-args และ --files-from file names กำลังถูกส่งจากโฮสต์หนึ่งไปยังอีกโฮสต์หนึ่งชื่อไฟล์จะถูกแปลจากชุดอักขระของโฮสต์ที่ส่งไปยังชุดอักขระของโฮสต์ที่รับ

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


23
โปรดทราบว่าคุณยังต้องระบุไดเร็กทอรีที่มีไฟล์ที่แสดงอยู่ตัวอย่างเช่นrsync -av --files-from=file-list . target/สำหรับการคัดลอกไฟล์จาก dir ปัจจุบัน
Nicolas Mattia

7
ใช่และขอย้ำ: The filenames that are read from the FILE are all relative to the source dir.
atp

อ๊ะพลาดไปขออภัย!
Nicolas Mattia

1
หากไฟล์จากไฟล์มีอะไรที่ขึ้นต้นด้วย..rsync ดูเหมือนจะเพิกเฉยต่อการ..ให้ข้อผิดพลาดแก่ฉันเช่นrsync: link_stat "/home/michael/test/subdir/test.txt" failed: No such file or directory(ในกรณีนี้เรียกใช้จาก dir "test" และพยายามระบุ "../subdir/test.txt" ซึ่งมีอยู่
Michael

สามารถ--files-fromรวมอาร์กิวเมนต์เข้ากับรายการรวมและไม่รวมโดยชัดแจ้งได้หรือไม่และไฟล์จากรายการจะถูกเพิ่มโดย--files-fromลบล้างกฎการยกเว้นที่มีอยู่หรือไม่เช่นจะรวมเข้าด้วยกันหากปรากฏในไฟล์
highsciguy

13

--files-from=พารามิเตอร์ต้องการเครื่องหมายทับหากคุณต้องการให้พา ธ สัมบูรณ์เหมือนเดิม ดังนั้นคำสั่งของคุณจะกลายเป็นดังนี้:

rsync -av --files-from=/path/to/file / /tmp/

สามารถทำได้เช่นมีไฟล์จำนวนมากและคุณต้องการคัดลอกไฟล์ทั้งหมดไปยัง x path ดังนั้นคุณจะพบไฟล์และส่งเอาต์พุตไปยังไฟล์ดังต่อไปนี้:

find /var/* -name *.log > file

9

สำหรับบันทึกไม่มีคำตอบใด ๆ ข้างต้นช่วยยกเว้นข้อเดียว สรุปได้ว่าคุณสามารถทำการสำรองข้อมูล--files-from=โดยใช้:

 rsync -aSvuc `แมว rsync-src-files` / mnt / d / rsync_test /

หรือ

rsync -aSvuc --recursive --files-from = rsync-src-files / mnt / d / rsync_test /

คำสั่งเดิมเป็นคำอธิบายในตัวเองข้างเนื้อหาของไฟล์rsync-src-filesซึ่งฉันจะอธิบายรายละเอียดด้านล่าง ตอนนี้หากคุณต้องการใช้เวอร์ชันหลังคุณต้องคำนึงถึงข้อสังเกตสี่ประการต่อไปนี้:

  1. สังเกตว่าจำเป็นต้องระบุทั้งสอง--files-fromและไดเร็กทอรีต้นทาง
  2. หนึ่งต้อง explicitely --recursiveระบุ
  3. ไฟล์rsync-src-filesนี้เป็นไฟล์ที่ผู้ใช้สร้างขึ้นและถูกวางไว้ในไดเร็กทอรี src สำหรับการทดสอบนี้
  4. rsyn-src-filesประกอบด้วยไฟล์และโฟลเดอร์เพื่อคัดลอกและพวกเขาจะนำมาเทียบกับไดเรกทอรีต้นทาง สำคัญ: ตรวจสอบว่าไม่มีช่องว่างต่อท้ายหรือบรรทัดว่างในไฟล์ ในตัวอย่างด้านล่างมีเพียงสองบรรทัดไม่ใช่สามบรรทัด (คิดออกโดยบังเอิญ) เนื้อหาของrsynch-src-filesคือ:

folderName1
folderName2


3

ฉันได้รับงานที่คล้ายกัน: เพื่อ rsync ไฟล์ทั้งหมดที่แก้ไขหลังจากวันที่กำหนด แต่ไม่รวมไดเรกทอรีบางรายการ การสร้างซับในแบบออล - อิน - วันนั้นเป็นเรื่องยากดังนั้นฉันจึงคิดปัญหาให้เป็นชิ้นเล็ก ๆ ทางออกสุดท้าย:

find  ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | egrep -v "/\..|Downloads|FOO" > FileList.txt
rsync -v --files-from=FileList.txt ~/sourceDIR /Destination

ก่อนอื่นฉันใช้find -L ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS". ฉันพยายามเพิ่มregexในfindบรรทัดเพื่อยกเว้นรูปแบบชื่อ แต่รสชาติของลินุกซ์ (มิ้นท์) ของฉันไม่เข้าใจการลบล้างนิพจน์ทั่วไปในfind. จำนวนรสชาติ regex ที่พยายาม - ไม่ได้ผลตามที่ต้องการ ดังนั้นฉันจึงจบลงด้วยegrep -v- ตัวเลือกที่ไม่รวมรูปแบบวิธีง่ายๆ ของฉันrsyncไม่ได้คัดลอกไดเรกทอรีเช่น/.cacheหรือ/.configรวมทั้งอื่น ๆ ที่ฉันตั้งชื่อไว้อย่างชัดเจน


1
ฉันเชื่อว่าคุณสามารถใช้การทดแทนกระบวนการเพื่อเปลี่ยนสิ่งนี้ให้เป็นbashหนึ่งซับได้:rsync -v --files-from=<(find ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | grep -Ev "/\..|Downloads|FOO") ~/sourceDIR /Destination
phk

2
$ date
  Wed 24 Apr 2019 09:54:53 AM PDT
$ rsync --version
  rsync  version 3.1.3  protocol version 31
  ...

ไวยากรณ์: rsync <file_/_folder_list> <source> <target>

ชื่อโฟลเดอร์ (ที่นี่มีการต่อท้าย/เช่นCancer - Evolution/) อยู่ในไฟล์รายการโฟลเดอร์ (เช่น: cm_folder_list_test):

# /mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test
# test file: 2019-04-24
Cancer/
Cancer - Evolution/
Cancer - Genomic Variants/
Cancer - Metastasis (EMT Transition ...)/
Cancer Pathways, Networks/
Catabolism - Autophagy; Phagosomes; Mitophagy/
Catabolism - Lysosomes/

หากคุณไม่รวมต่อท้าย/โฟลเดอร์เป้าหมาย rsync จะถูกสร้างขึ้น แต่ว่างเปล่า

ชื่อโฟลเดอร์เหล่านั้นถูกต่อท้ายไปยังส่วนที่เหลือของพา ธ ( /home/victoria/Mail/2_RESEARCH - NEWS) ดังนั้นจึงให้พา ธ โฟลเดอร์ทั้งหมดไปยัง rsync; เช่น: /home/victoria/Mail/2_RESEARCH - NEWS/Cancer - Evolution/.

โปรดทราบว่าคุณต้องใช้--files-from=... , ไม่ใช่--include-from=...

rsync -aqP --delete --files-from=/mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test "/home/victoria/Mail/2_RESEARCH - NEWS" $IN/

(ในสคริปต์ BASH ของฉันฉันกำหนดตัวแปร$INดังนี้)

BASEDIR="/mnt/Vancouver/projects/ie/claws"
IN=$BASEDIR/data/test/input

ตัวเลือก rsync ที่ใช้:

 -a  :   archive: equals -rlptgoD (no -H,-A,-X)
    -r  :   recursive
    -l  :   copy symlinks as symlinks
    -p  :   preserve permissions
    -t  :   preserve modification times 
    -g  :   preserve group 
    -o  :   preserve owner (super-user only) 
    -D  :   same as --devices --specials 
  -q  :   quiet (/server/547106/run-totally-silent-rsync)

  --delete
    This  tells  rsync to delete extraneous files from the RECEIVING SIDE (ones
    that AREN’T ON THE SENDING SIDE), but only for the directories that are
    being synchronized.  You must have asked rsync to send the whole directory
    (e.g.  "dir" or "dir/") without using a wildcard for the directory’s contents
    (e.g. "dir/*") since the wildcard is expanded by the shell and rsync thus
    gets a request to transfer individual files, not the files’ parent directory.
    Files  that  are  excluded  from  the transfer are also excluded from being
    deleted unless you use the --delete-excluded option or mark the rules as
    only matching on the sending side (see the include/exclude modifiers in the
    FILTER RULES section).  ...

1

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

เมื่อวิเคราะห์ปัญหาคุณควรเปิดใช้งานตัวเลือกการดีบัก -vv

จากนั้น rsync จะแสดงไฟล์ที่รวมหรือแยกออกโดยรูปแบบ:

building file list ... 
[sender] hiding file FILE1 because of pattern FILE1*
[sender] showing file FILE2 because of pattern *

0

ไม่มีคำตอบเหล่านี้ทำงานให้กับฉันเมื่อสิ่งที่ผมต้องเป็นรายชื่อของไดเรกทอรี แล้วฉันก็สะดุดกับวิธีแก้ปัญหา! คุณจะต้องเพิ่ม-rไป--files-fromเพราะ-aจะไม่ถูกเรียกซ้ำในสถานการณ์นี้ (ที่รู้ ?!)

rsync -aruRP --files-from=directory.list . ../new/location

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