คัดลอกไฟล์และโฟลเดอร์ทั้งหมดยกเว้นไฟล์และโฟลเดอร์การโค่นล้มใน OS X


14

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

ฉันคิดว่าฉันจะพบว่าจำเป็นต้องยกเว้นไฟล์หลายประเภทในอนาคตอันใกล้ ตัวอย่างเช่นฉันอาจต้องการยกเว้น. svn, * .bak และ * .prj

นี่คือสิ่งที่ฉันรวบรวมไว้ด้วย แต่ก็ไม่ได้ผลสำหรับฉัน ส่วนแรกพบกับผลงาน แต่ฉันทำอะไรผิดพลาดกับxargsและซีพี ฉันพยายามCP-Rที่มีและไม่มี นอกจากนี้ฉันใช้ OS X และดูเหมือนจะมีxargsรุ่นที่มีคุณลักษณะน้อยกว่าระบบ linux

find ./sourcedirectory -not \( -name .svn -a -prune \)
     | xargs -IFILES cp -R FILES ./destinationdirectory

ฉันอาจจะผิด แต่ฉันคิดว่านี่เป็นเรื่องยากกว่าที่คุณคิด แม้ว่าfindคำสั่งของคุณจะใช้อย่างถูกต้อง-pruneเพื่อแยกรายการ. svn จากนั้นคุณก็ผ่านการ-Rตั้งค่าสถานะcpที่บอกให้คำสั่งนั้นเรียกซ้ำ เมื่อทำเช่นนั้นคุณจะสูญเสียสิ่งที่คุณมีในfindคำสั่ง ฉันจะคนจรจัดกับสิ่งนี้เป็นเวลาหนึ่งนาที แต่ฉันคิดว่าคำตอบไม่ได้ใช้-Rในcpคำสั่ง
Telemachus

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

มันเป็น-Rธงฉันค่อนข้างแน่ใจ ลบที่และคุณควรจะดี (แม้ว่าคุณอาจต้องการที่จะเพิ่ม-mindepth 1เพื่อละเว้นโฟลเดอร์ไดเรกทอรีระดับบนสุดที่คุณไม่ต้องการคัดลอกผมถือว่า)
เทเล

ฉันมักจะทำสิ่งเหล่านี้โดยการคัดลอกทุกอย่างแล้วลบไฟล์ที่ไม่ต้องการในไดเรกทอรีเป้าหมาย ซึ่งมักจะง่ายกว่ามาก
ม.ค. Doggen

คำตอบ:


22

(แก้ไขหลังจากอ่านคำถามอีกครั้ง Questioner บอกว่าไม่ได้ติดตั้ง rsync)

ปัญหาที่อาจเกิดขึ้นกับโซลูชัน find / xargs ของคุณคือช่องว่างในชื่อไฟล์ หากต้องการหลีกเลี่ยงให้บอก find และ xargs เพื่อใช้อักขระ null (ASCII 0) เพื่อแยกไฟล์ที่พบ:

find ./sourcedirectory -not ( -name .svn -a -prune ) -print0 | xargs -0 -IFILES cp FILES ./destinationdirectory

หากคุณพบว่า rsync พร้อมใช้งานฉันยังคงคิดว่า rsync เป็นทางออกที่ดีกว่า:

ใช้ rsync พร้อมกับตัวเลือก -C จากหน้าrsync :

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

สิ่งนี้จะบอก rsync ให้ละเว้นรูปแบบเหล่านี้:

RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state .nse_depinfo *~
#* .#* ,* _$* *$ *.old *.bak *.BAK *.orig *.rej .del-* *.a *.olb *.o *.obj 
*.so *.exe *.Z *.elc *.ln core .svn/ .git/ .bzr/

ตัวอย่างเช่น:

rsync -avC /path/to/source/directory /path/to/destination/directory

(หมายเหตุ: หากคุณยังไม่คุ้นเคยกับ rsync โปรดอ่านหน้าคนนั้นเกี่ยวกับวิธีที่ rsync เกี่ยวข้องกับเครื่องหมายสแลชต่อท้ายในพา ธ ต้นทางซึ่งจะทำงานแตกต่างกันหากคุณใส่เครื่องหมายสแลชมากกว่าที่คุณไม่ต้องการ ค้นหา 'trailing slash')


โอ้หนูฉันเพิ่งอ่านคำถามของคุณอีกครั้งและเห็นว่าคุณบอกว่าคุณไม่ได้ติดตั้ง rsync บน MacBook Pro ของฉัน (OS X 10.6.1) มันอยู่ใน / usr / bin / rsync มันถูกติดตั้งสำหรับฉันภายใต้ Tiger (10.4) และ Leopard (10.5) ด้วย
Doug Harris

ฉันค่อนข้างมั่นใจว่าคุณ (และ OP) ไม่ต้องการ-Rแฟล็กในxargsส่วนของคำสั่ง
Telemachus

เยี่ยมมากฉันคัดลอกมาจากคำถามเดิม จะแก้ไขทันที
ดั๊กแฮร์ริส

1
ขอบคุณดั๊ก! สิ่งหนึ่งที่ฉันสั่งสอนคือ "ใช้เครื่องมือที่เหมาะสมสำหรับงาน" ฉันเพิ่งมาจากโลก Windows ถึง OSX และฉันยังคงคลำไปรอบ ๆ ในความไม่รู้ ฉันโพสต์คำถามเดียวกันนี้ในช่อง linux และมีคนพูดอย่างรวดเร็วเพียงแค่ใช้ "rsynch" ฉันพิมพ์ "rsynch" ในเทอร์มินัลแล้วเห็นว่ามันไม่มีอยู่จริงและตรวจสอบการค้นหาต่อ | วิธีการ xargs ฉันดื้อรั้นแบบนี้ อย่างไรก็ตาม OSX จะมี "rsync" เป็นค่าเริ่มต้นและโพสต์ของคุณมีประโยชน์มาก ฉันไม่มีประสบการณ์มากพอที่จะรู้ว่าสิ่งใดดีกว่ากัน แต่ rsync แน่ใจว่ากระชับกว่านี้มาก ขอบคุณ!
ไมเคิลคอตต์

หากคุณจะทำงานใด ๆ กับเครื่อง linux นอกเหนือจากงานของคุณบน OS X ฉันคิดว่าคุณจะต้องเสียเวลาในการเรียนรู้วิธีใช้ rsync ฟังก์ชั่นหลักของมันคือการคัดลอกเฉพาะสิ่งที่เปลี่ยนแปลง (เช่น robocopy บน windows หากคุณคุ้นเคยกับมัน) เนื่องจากเป็นการคัดลอกเฉพาะส่วนที่เป็นเดลต้าจึงเป็นวิธีที่ยอดเยี่ยมในการจัดการการสำรองข้อมูล (ไม่ใช่เครื่องเวลา) การปรับใช้รหัสและสิ่งที่คล้ายกัน
Doug Harris

2

ไม่ใช่โซลูชันทั่วไป แต่ ... คุณสามารถใช้คำสั่ง svn export เพื่อสร้างสำเนาของเวิร์กสเปซโดยไม่มีโฟลเดอร์. svn metadata


ไม่เป็นการล่วงละเมิด แต่ฉันไม่แน่ใจว่าทำไมคำตอบนี้จึงได้รับการโหวต ฉันตระหนักถึงความสามารถของ svn แต่ "ฉันต้องการวิธีการแก้ปัญหาทั่วไปที่กระชับ แต่ฉันคิดว่าฉันจะพบว่าจำเป็นต้องแยกไฟล์หลายประเภทในอนาคตอันใกล้"
Michael Prescott

2
%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn  | tar xvf - -C FOLDER_OUT )

หากคุณต้องการคุณสามารถใส่ 'pv' หรือสิ่งที่คล้ายกันในระหว่างกระบวนการ tar 2


2

วิธีที่สกปรก แต่รวดเร็วและรัดกุม:

cp -r source destination
find destination -iname .svn |xargs rm -rf

สิ่งนี้จะคัดลอกไดเรกทอรีหนึ่งไปยังอีกไดเรกทอรีหนึ่ง (ดังนั้นจึงเป็นตัวเลือกแบบเรียกซ้ำ-r) และจากนั้นจะลบสิ่งที่ชื่อซ้ำ.svn(ไม่สนใจกรณี)


1

ฉันจะใช้วิธีอื่นโดยใช้ tar และกลไกที่แยกออก

จากในไดเรกทอรีปลายทาง:

tar -X excludefile -C source -f - . | tar xf -

สิ่งนี้จะซีดีไปที่แหล่งเนื้อหาเนื้อหายกเว้นสิ่งที่ระบุไว้ในไม่รวมไฟล์แล้ว untar ไปยังไดเรกทอรีปัจจุบัน


ทางออกที่สง่างามแน่นอน
Nick Stinemates

เป็นคำตอบเดียวกับที่ฉันให้ในภายหลัง รวมทั้งคุณต้องอยู่ในไดเรกทอรีปลายทาง ... :)
akira

0

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

find source/  -mindepth 1 -not \( -name .svn -prune \) | xargs -Iitem cp item target/

-mindepth 1ธงบอกfindจะไม่สนใจไดเรกทอรีระดับบนสุด เนื่องจากคุณต้องการคัดลอกเนื้อหาทั้งหมดของไดเรกทอรีนั้นลงในไดเรกทอรีระดับบนสุดใหม่ฉันคิดว่าคุณไม่ต้องการสิ่งนั้น

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


ขอบคุณ Telemachus มันมีประโยชน์ ฉันไม่ได้มีประสบการณ์ในการวิจารณ์ แต่ฉันจะทำซ้ำสิ่งที่ฉันได้รับการบอกเล่าตั้งแต่โพสต์เดิมของฉัน "xargs is broken" ผู้วิจารณ์ irc ที่ไม่รู้จักที่บอกฉันว่าเป็นแรงบันดาลใจให้ฉันมองไปรอบ ๆ อีกเล็กน้อยและฉันคิดว่าคำตอบของ Doug Harris แก้ปัญหาได้ นั่นบอกให้ xargs ใช้ตัวอักษรว่าง ฉันคิดว่านั่นคือสวิตช์ -0?
Michael Prescott

@Michael: xargsไม่เสีย แต่ในระบบที่คล้าย Unix ค่าดีฟอลต์คือไม่ใช้ชื่อไฟล์ (หรือชื่อไดเรกทอรี) ที่มีช่องว่าง หากคุณมีช่องว่างหรือตัวละคร "ตลก" ในชื่อไฟล์ (หรือชื่อไดเรกทอรี) คุณต้องทำงานพิเศษเพื่อจัดการกับสิ่งนั้น (ใน GNU findมีส่วนทั้งหมดในmanหน้าชื่อ "ไฟล์ผิดปกติ" เนื่องจากปัญหานี้) -0ตั้งค่าสถานะในxargsและ-print0เพื่อfindช่วยในการจัดการปัญหาเหล่านี้ อย่างไรก็ตามฉันสัญญากับคุณว่าคุณไม่ต้องการใช้-Rคำสั่งคัดลอก มันจะยกเลิกสิ่งที่คุณทำเพื่อหลีกเลี่ยงไดเรกทอรี SVN
Telemachus

0

ฉันคิดว่ามันขึ้นอยู่กับว่าต้นไม้ของคุณใหญ่แค่ไหน แต่ทำไมไม่คัดลอกทุกอย่างก่อนแล้วจึงตัดแต่งโฟลเดอร์. svn หลัง:

find /dest-dir -type d -name .svn -exec rm -rf {} \;

?


ความคิดเริ่มต้นของฉันก็คือว่านี่เป็นการวนรอบของ CPU ซ้ำซ้อน: การคัดลอกและการลบ อาจต้องใช้เวลาเพิ่มสักหน่อยในการสร้างfindคำสั่งที่ถูกต้องแต่คุณทำได้เพียงครั้งเดียว คุณสามารถใช้คำสั่งหลายร้อยครั้งเมื่อคุณทำให้ถูกต้อง
Telemachus

@ Telemachus - จริง แต่นั่นเป็นสิ่งที่คอมพิวเตอร์ (ควรจะ) เก่ง - ทำสิ่งที่ยุ่งยากดังนั้นเราไม่จำเป็นต้องทำ! จริง ๆ - มีอันตรายอะไรในการคัดลอกไฟล์บางไฟล์เท่านั้นที่จะลบทิ้งในไม่ช้าถ้ามันหมายถึงคำสั่งที่คุณประดิษฐ์ให้ทำมันง่ายมาก?
Steve Folly

@ Steve: ไม่มีอันตรายจริงๆ เท่านี้จะเป็นทางออกที่ดี เป็นไปตามหลักการเดียวที่ฉันชอบ: "ทำสิ่งที่ง่ายที่สุดที่เป็นไปได้" ในทางตรงกันข้ามมันละเมิดหลักการอื่นที่ฉันชอบมากยิ่งขึ้น: "เรียนรู้เครื่องมือของคุณ" ฉันต้องการเรียนรู้วิธีใช้งานfindตัวเองให้ดีขึ้นเพื่อที่ฉันจะได้ไม่ต้องทำสิ่งนี้ แต่คุณพูดถูก: ไม่มีอะไรผิดปกติกับโซลูชันนี้
Telemachus

@Telemachus: ฉันเห็นด้วยกับ "เรียนรู้เครื่องมือของคุณ" เมื่อผมเริ่มออกผมว่าหาคำสั่งของฉันข้างต้นจะได้ดูคลุมเครือมากกับผมแล้ว :-)
สตีฟเขลา


0

คุณยังสามารถทำสิ่งที่ตรงกันข้าม คัดลอกทุกอย่างแล้วลบโฟลเดอร์. svn โดยใช้คำสั่งด้านล่าง:

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