คัดลอกเนื้อหาไดเรกทอรีโดยใช้คำสั่ง 'cp'


33

คุณจะคัดลอกเนื้อหาทั้งหมดของไดเรกทอรีหนึ่งไปยังอีกไดเรกทอรีหนึ่งได้อย่างไร

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

$ cd /home/newuser
$ cp -a /backup/olduser/* .

ปัญหาดังกล่าวข้างต้นคือรูปแบบที่แวววาว '*' ตรงกับไดเรกทอรีที่ซ่อนอยู่ '' และ '.. ' แล้วคุณจะพบกับไดเรกทอรี 'olduser' ใน 'newuser' รวมถึงเนื้อหา

คุณสามารถทำสิ่งนี้:

$ rmdir /home/newuser
$ cp -a /backup/olduser /home/newuser

แต่ถ้าผู้ใช้ใหม่มีไฟล์และไดเรกทอรีเริ่มต้นอยู่แล้ว

อะไรคือวิธีที่ง่ายที่สุดถูกต้องที่สุดจดจำได้ง่ายที่สุดและไม่ยุ่งเหยิงในการย้ายเนื้อหาของไดเรกทอรีหนึ่งไปยังอีกไดเรกทอรีหนึ่งโดยใช้คำสั่ง 'cp' พื้นฐานและเชลล์?

คำตอบ:


31

ลอง:

cp -ra /backup/olduser/. /home/newuser

นี่ยอดเยี่ยม แต่ฉันไม่สามารถเข้าใจได้อย่างชัดเจนว่ามันทำงานอย่างไร ฉันคิดว่าอาจเป็นเพราะฉันไม่เข้าใจวิธีการ.และการ..ทำงาน สนใจที่จะอธิบาย?
bradley.ayers

สิ่งนี้ใช้ได้สำหรับฉัน แต่cp -r ./a bไม่ได้ มีความคิดอะไรไหม
Brig

3
ใช้งานได้สำหรับฉันเช่นกัน แต่rไม่จำเป็นต้องใช้ตัวเลือก ตัวเลือกที่หมายถึงa r
MountainX

1
ดูเหมือนว่าพารามิเตอร์ -r จะซ้ำซ้อนเล็กน้อย ณ จุดนี้!
Master of Celebration

-aพารามิเตอร์ไม่มีอะไรที่จะช่วยเหลือในสถานการณ์เช่นนี้ คำสั่งที่cp -r ./a/. bจะคัดลอกเนื้อหาและเนื้อหาเฉพาะของไดเรกทอรีลงในไดเรกทอรีa bการ-aตั้งค่าสถานะเก็บรักษาลิงก์เวลาประทับ ฯลฯ ซึ่งไม่เกี่ยวข้องกับคำถาม
Steen Schütt

23

สองไดเรกทอรี a และ b

ทั้งคู่มีไฟล์มา

คุณอยู่ในไดเรกทอรีที่มี a และ b

cp -r ./a b

-r = เรียกซ้ำ


คุณไม่ต้องการให้ -a รับไฟล์ทั้งหมดใช่ไหม
bw

7
อาร์กิวเมนต์ -a ไม่มีอะไรเกี่ยวข้องกับไฟล์ทั้งหมดมันสั้นสำหรับการเก็บถาวรมันจะรักษาความเป็นเจ้าของไฟล์สิทธิ์การเข้าถึงเวลา ฯลฯ อาร์กิวเมนต์ -a (ในขณะที่มีประโยชน์สูง) ไม่ใช่ตัวเลือกมาตรฐานและการใช้ cp หลายตัว ไม่ได้ให้มัน
theotherreceive

1
@mch: รวมโดยอัตโนมัติเพราะคุณเคยบอกcpเพื่อคัดลอกไดเรกทอรีaและมีอยู่โดยa/.somedotfile aถ้าbมีอยู่แล้วคำสั่งนี้จะสร้างสำเนาถูกต้องของที่a b/a
ต้มตุ๋น Quixote

2
วิธีง่ายๆ:cp -R /some/dir/* /another/dir
n0pe

1
สิ่งนี้คัดลอก a / foo ไปยัง b / a / foo แทนที่จะไปที่ b / foo
Sparr

19

โปรดจำไว้ว่าโดยค่าเริ่มต้นให้cpคัดลอกไดเรกทอรีแรกไปยังไดเรกทอรีที่สองหากมีอยู่จริง

ยกตัวอย่างเช่นcp -r a bจะคัดลอกไดเรกทอรี เข้าa bถ้าไม่อยู่ก็จะถูกสร้างขึ้นด้วยเนื้อหาของba

หากคุณต้องการคัดลอกเนื้อหาของaลงในb(ตัวอย่างเช่นเมื่อคัดลอกทั้งระบบไฟล์ลงในจุดเมานท์) ให้ใช้:

cp -r a/. b

เหมือนในคำตอบก่อนหน้า

โปรดทราบว่า-aใช้ในคำตอบอื่น ๆ บางคำเหมือน-dr --preserve=allและจะรักษาเวลาประทับบริบทและแอตทริบิวต์เพิ่มเติม


วิธีการที่ไม่/.ทำงานหรือไม่
bradley.ayers

a/.แสดงถึงเนื้อหาของไดเรกทอรี 'a' ซึ่งตรงข้ามกับไดเรกทอรีตัวเองในสถานการณ์ส่วนใหญ่มันมีความหมายเหมือนกัน แต่เมื่อใช้cp -rมันจะหลีกเลี่ยงพฤติกรรมเริ่มต้นของ cp (การคัดลอก INTO b)
Nicolas Bonnefon

เคล็ดลับที่น่ากลัวนี่คือสิ่งที่ฉันกำลังมองหา แต่ไม่สามารถหาที่อื่นได้ทั้งหมด - 'foo / *' หรือ '-r foo /' ที่ล้มเหลวในกรณีมุม
Tener

@TimoHuovinen '.' ไม่ใช่สัญลักษณ์แทนเลย เป็นไดเรกทอรี "parent" อย่างแท้จริงและ '.. ' เป็นปู่ย่าตายาย ซึ่งหมายความว่า '/foo/./././///' เป็นไดเรกทอรีเดียวกันกับ '/ foo' และ '/ foo / bar / .. ' เป็นไดเรกทอรีเดียวกับ '/ foo' คิดว่าพวกเขาเป็นลิงก์ที่สร้างขึ้นในระบบไฟล์
quuxman

@ quuxman ขอบคุณฉันไม่ได้ตระหนักถึงมันในตอนนั้น ฉันจะลบความคิดเห็นเก่าของฉันเพื่อหลีกเลี่ยงคนที่สับสน
Timo Huovinen

6

หากคุณไม่ได้กำหนดค่าเปลือกของคุณใหม่อย่างจริงจังรูปแบบการวนรอบ '*' ไม่ตรงกับ '.' หรือ '.. ' ตามที่คุณสามารถตรวจสอบได้โดยใช้ echo * สิ่งที่มันทำแทนคือละเว้นไฟล์ที่ชื่อขึ้นต้นด้วย '.' ดังนั้นวิธีการของคุณจะพลาดไฟล์ที่ซ่อนอยู่ทั้งหมด คุณสามารถปรับแต่งพฤติกรรมนี้ด้วยตัวเลือกเชลล์ตัวอย่างเช่นตัวเลือก dotglob ใน bash แต่จากนั้นจะไม่เป็นตัวเลือกแบบพกพาและมีประสิทธิภาพที่คุณกำลังมองหา

หากคุณต้องการทำสิ่งนี้มากกว่าหนึ่งครั้งหรือสองครั้งฉันขอแนะนำให้คุณดูเป็น rsync หรือพร้อมเพรียงกัน (ขึ้นอยู่กับความต้องการเฉพาะ) ด้วยแหล่งข้อมูลและเป้าหมายที่ออกแบบมาอย่างพิถีพิถัน

อีกทางเลือกหนึ่งคือการวางไดเรกทอรีแหล่งที่มาใน tarball และ untar มันเหนือไดเรกทอรีเป้าหมายที่มีอยู่


1
ฉันใช้สิ่งนี้: ( cd /src/dir ; tar cf - . ) | ( cd /dest/dir ; tar xf - )... tar cf - .tar ของไดเร็กตอรี่ซอร์ส, dotfiles รวมอยู่, และ spits ไปที่ STDOUT, ซึ่งได้รับไพพ์ไปยัง STDIN ของtar xf -.
ต้มตุ๋น Quixote

ฉันคิดว่าจุดรวมของ OP คือวิธีการอ้างอิงไฟล์ที่ขึ้นต้นด้วย '.' แต่ไม่ใช่ของพิเศษ '.' และไดเรกทอรี '.. ' มีวิธีแก้ปัญหาที่สวยงามกว่าด้านบนแทนการใช้ rsync หรือโปรแกรมที่ซับซ้อนอื่น ๆ
quuxman

2

การทำเช่นนี้จะเป็นการคัดลอกทั้งไฟล์ปกติและไฟล์ที่ถูกซ่อนขณะยกเว้นไดเรกทอรีหลัก ( ..):

cd /directory/to/copy
cp -r * .[^.]* /destination/directory

หากคุณไม่แยกไดเรกทอรีหลักคุณจะพบเนื้อหาทั้งหมด..ในไดเรกทอรีปลายทางด้วยเช่นกัน


1
แต่สิ่งนี้ยังไม่รวมชื่อที่ขึ้นต้นด้วย .. (เช่น...หรือ..super-hidden)
สกอตต์

0

ในการคัดลอกไฟล์ที่ขึ้นต้นด้วยจุดเพียงแค่ทำ cp. * target /

ดังนั้นที่ง่ายที่สุดคือทำคำสั่ง cp สองครั้ง

ในฐานะที่เป็น Peter Eisentraut sais กฎที่ทำให้เป็นทรงกลมปกติไม่ได้รวม .. และ (อืมจะจบประโยคนี้อย่างไร?;)

เพียงใช้ -r เพื่อทำให้มันเกิดซ้ำและ -i เพื่อให้ cp ถามว่าคุณต้องการเขียนทับไฟล์จริงๆหรือไม่

cp -ri /backup/olduser/* /newuser/
cp -ri /backup/olduser/.* /newuser/

มักจะ*ไม่ตรง.หรือแต่มันก็ไม่ได้ถ้าคุณใช้.. .*ลองecho .*ดู คุณสามารถยกเว้น.และมีรูปแบบต่อไปนี้:.. .[^.]*
mch

@mch: แต่.[^.]*ก็ยังไม่รวมชื่อที่ขึ้นต้นด้วย .. (เช่น...หรือ..super-hidden)
สกอตต์

0

สิ่งนี้ใช้สำหรับการคัดลอกไฟล์และไดเรกทอรีทั้งหมดยกเว้นไดเรกทอรีที่ซ่อนอยู่ซ้ำ ๆ จากไดเรกทอรีปัจจุบันไปยังที่ใดก็ได้:

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