วิธีการคัดลอกด้วย cp เพื่อรวมไฟล์ที่ซ่อนอยู่และไดเรกทอรีที่ซ่อนอยู่และเนื้อหาของพวกเขา?


392

ฉันจะให้cp -rคัดลอกทุกอย่างของไฟล์และไดเรกทอรีในไดเรกทอรี

ที่ต้องการ:

  • รวมไฟล์ที่ซ่อนอยู่และไดเรกทอรีที่ซ่อนอยู่
  • เป็นคำสั่งเดียวที่มีการตั้งค่าสถานะเพื่อรวมข้างต้น
  • ไม่จำเป็นต้องพึ่งพาการจับคู่รูปแบบเลย

น่าเกลียดของฉัน แต่ทำงานแฮ็คคือ:

cp -r /etc/skel/* /home/user
cp -r /etc/skel/.[^.]* /home/user

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


1
คำตอบเพิ่มเติมที่นี่แม้ว่าพวกเขาจะดูไม่ดี serverfault.com/questions/3154/…
Roel Van de Paar

ได้โปรด, Eleven81, พิจารณาการเปลี่ยนคำตอบที่ยอมรับให้กับ @bruno pereira, เพราะมันหลีกเลี่ยงการสร้างโฟลเดอร์ใหม่ ถ้าไม่ให้ความคิดเห็นนี้เป็นคำเตือนแก่ผู้อ่านใหม่เพื่อตรวจสอบคำตอบอื่น ๆ (โหวตมากที่สุด) Tx
ดร. Beco

คำตอบ:


265

อย่าระบุไฟล์:

cp -r /etc/skel /home/user

(โปรดทราบว่า/home/userจะต้องไม่มีอยู่แล้วไม่เช่นนั้นจะสร้าง/home/user/skelขึ้น)


61
มันเป็นไปได้ที่จะใช้สิ่งที่คล้ายกันถ้า/home/user/skel ไม่อยู่?
bradley.ayers

@ bradley.ayers ฉันคิดว่ามีใครสามารถคัดลอกไปยังไดเรกทอรีย่อยชั่วคราวจากนั้นย้ายพวกเขาไปยังระดับบน (เนื่องจากการย้ายในไดรฟ์เดียวกันนั้นรวดเร็ว) น้อยกว่าอุดมคติ แต่สั้นกว่าโซลูชันอื่นสำหรับฉัน
Halil Özgür

7
@ bradley.ayers คำตอบของ Bruno ด้านล่างตอบคำถามของคุณ
Mark

1
วิธีนี้ไม่ได้ผลสำหรับฉัน มันไม่ได้คัดลอกไฟล์ที่ซ่อนอยู่ ฉันใช้ CentOS รีลีส 6.5 วิธีการแก้ปัญหาของ @ Bruno ทำเคล็ดลับ
Technext

2
ภายใต้ ubuntu / debian จะวางไดเรกทอรี 'skel' ไว้ในไดเรกทอรีเป้าหมายและไม่ใช่ไฟล์ที่เรียกซ้ำภายใน skel ใช้-T(ไม่มีเป้าหมาย) ต่อด้านล่างเพื่อการใช้งานที่เหมาะสม ( -rTสำหรับเรียกซ้ำ)
bshea

468

ให้บอกว่าคุณสร้างโฟลเดอร์ใหม่ (หรือกำลังจะสร้างขึ้นใหม่) และต้องการคัดลอกไฟล์ไปยังไฟล์หลังจากสร้างโฟลเดอร์แล้ว

mkdir /home/<new_user>
cp -r /etc/skel/. /home/<new_user>

นี่จะเป็นการคัดลอกไฟล์ / โฟลเดอร์ทั้งหมดซ้ำจาก/etc/skelในไปยังโฟลเดอร์ที่มีอยู่แล้วที่สร้างขึ้นในบรรทัดแรก


5
หากฉันไม่เข้าใจผิดนี่ไม่ได้คัดลอกไฟล์ซ่อน / จุด
Halil Özgür

34
ทำงานได้ดีสำหรับฉัน โปรดทราบว่า '.' มีความสำคัญต่อการทำงาน
ทำเครื่องหมาย

12
มันใช้งานได้ แต่ทำไม ไม่พบการอ้างอิงถึงสิ่งนี้ในคู่มือ
Julien Palard

5
ฉันคิดว่ามันใช้งานได้เพราะโดยปกติสิ่งนี้จะสร้างโฟลเดอร์ใหม่ที่มีชื่อของโฟลเดอร์สุดท้ายในอาร์กิวเมนต์แรก อย่างไรก็ตามเนื่องจากชื่อนั้น.พฤติกรรมนี้จึงต้องการให้สร้างไดเรกทอรีที่มีอยู่แล้วดังนั้นจึงข้ามขั้นตอนนั้นไป
Zenexer

28
@Technext ค่าเริ่มต้นการวนเป็นวงกลมใน bash ไม่รวมชื่อไฟล์ที่ขึ้นต้นด้วย a .เพื่อเปลี่ยนว่าคุณต้องใช้shopt -s dotglobคำสั่งก่อนจึงจะสามารถรวมไฟล์เหล่านั้นได้ ดังนั้น*โดยค่าเริ่มต้นคุณจะต้องคัดลอกไฟล์ทั้งหมดจากไดเรกทอรีนี้ซ้ำซึ่งสามารถขยายการใช้*(ซึ่งไม่รวมไฟล์ที่ซ่อนอยู่โดยค่าเริ่มต้น) ในขณะที่.คุณกำลังใช้ cp เพื่อทำสำเนาทุกอย่างซ้ำ ๆ จาก "ไดเรกทอรีนี้"
Bruno Pereira

79

วิธีที่ถูกต้องในการทำเช่นนี้คือการใช้-T (--no-target-directory)ตัวเลือกและคัดลอกโฟลเดอร์ซ้ำ (โดยไม่ต้องต่อท้ายสแลชเครื่องหมายดอกจัน ฯลฯ ) เช่น:

cp -rT /etc/skel /home/user

สิ่งนี้จะคัดลอกเนื้อหาของ/etc/skelไปยัง/home/user(รวมถึงไฟล์ที่ซ่อนอยู่) สร้างโฟลเดอร์/home/userหากไม่มีอยู่ อย่างไรก็ตาม-Tตัวเลือกป้องกันเนื้อหาของ/etc/skelการคัดลอกไปยังโฟลเดอร์ใหม่/home/user/skelควรมีโฟลเดอร์/home/userอยู่


3
คำตอบที่ถูกต้อง +1
bshea

นี่เป็นคำตอบที่ถูกต้องแน่นอน
Gaetan

นี่คือคำตอบที่ดีที่สุดของพวง; เพียงคนเดียวที่จะช่วยแก้ปัญหาได้โดยไม่ต้องแทรกซ้อนมัน
ZaxLofful

ทำงานเพื่อคัดลอกอย่างที่คาดไว้
Chetabahana

รักมันเมื่อคุณใช้ค่าสถานะ cmd ที่ถูกต้องสำหรับเคสเดียว
Tran Triet

66

bashตัวเองมีทางออกที่ดีก็มีshell optionคุณสามารถcp, mvและอื่น ๆ .:

shopt -s dotglob # for considering dot files (turn on dot files)

และ

shopt -u dotglob # for don't considering dot files (turn off dot files)

วิธีแก้ปัญหาดังกล่าวเป็นมาตรฐานของ bash

บันทึก:

shopt # without argument show status of all shell options
-u # abbrivation of unset 
-s # abbrivation of set

2
มีประโยชน์เมื่อคุณต้องการคัดลอกเฉพาะเนื้อหาโดยไม่ต้องสร้างไดเรกทอรีใหม่ภายในปลายทาง โดยเฉพาะอย่างยิ่งเมื่อปลายทาง dir เป็นจุดเชื่อมต่อ
kaszynek

3
นี่เป็นคำตอบที่ดีที่สุดและเข้ามาสู่หัวใจของคำถาม ..
Stephen Stephen

7
มันsetoptสำหรับ zsh ในกรณีที่คนอื่นสงสัย
Pat

25

ใช้ rsync:

rsync -rtv source_folder/ destination_folder/


ตัวเลือกที่ดีที่สุดสำหรับฉันแม้ว่าฉันจะใช้ - ความคืบหน้าเพื่อให้ข้อเสนอแนะเพิ่มเติมเกี่ยวกับกระบวนการทั้งหมด
Edenshaw

5

rsync ดี แต่มีทางเลือกอื่น:

cp -a src/ dst/

จากความช่วยเหลือหลัก:

   -a, --archive
          same as -dR --preserve=all

   -d     same as --no-dereference --preserve=links

   -R, -r, --recursive
          copy directories recursively

ฉันมักจะใช้ cp -r ขอบคุณที่พูดถึง cp -a
Pinaki Mukherjee

4

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

cp -R /etc/skel /home/

สิ่งนี้จะคัดลอกไดเร็กทอรี / etc / skel ไปยัง / home / รวมถึงไฟล์และไดเรกทอรีที่ซ่อนอยู่

ในที่สุดคุณสามารถคัดลอกไดเรกทอรีและเปลี่ยนชื่อในบรรทัดเดียว:

cp -R /etc/skel /home/ && mv /home/skel /home/user

หรือคุณสามารถใช้cp -r /etc/skel /home/userเพื่อเปลี่ยนชื่อskelเป็นuser...
David

ถูกต้องก็ต่อเมื่อ / home / ผู้ใช้ยังไม่มีอยู่
Gabriel Hautclocq

4

คุณสามารถใช้ rsync

rsync -aP ./from/dir/ /some/other/directory/

คุณสามารถคัดลอกผ่าน ssh

rsync -aP ./from/dir/ username@remotehost:/some/other/directory/

มีแฟล็กต่างๆที่คุณสามารถใช้ได้: -a, --archive # archive (-rlptgoD)

-r, --recursive
-l, --links      # copy symlinks as links
-p, --perms      # preserve permissions
-t, --times      # preserve times
-g, --group      # preserve group
-o, --owner      # preserve owner
-D               # --devices --specials

--delete         # Delete extra files

You may want to add the -P option to your command.

--partial        # By default, rsync will delete any partially transferred file if the transfer is interrupted. In some circumstances it is more desirable to keep partially transferred files. Using the --partial option tells rsync to keep the partial file which should make a subsequent transfer of the rest of the file much faster.

-P               # The -P option is equivalent to --partial --progress.   Its  purpose  is to make it much easier to specify these two options for a long transfer that may be interrupted.

Rsync man page


4

วิธีที่ง่ายที่สุดคือ:

cp -r /etc/skel/{.,}* /home/user

การแสดงออก{.,}*รวมถึงไฟล์และไดเรกทอรีทั้งหมด (เริ่มต้นด้วยจุด)

หากคุณไม่ต้องการใช้นิพจน์ด้านบนคุณสามารถใช้cpคุณสมบัติซึ่งเป็นความสามารถในการระบุหลายแหล่งสำหรับโฟลเดอร์เป้าหมายหนึ่งโฟลเดอร์:

cp -r /etc/skel/* /etc/skel/.* /home/user

1
สิ่งนี้อาจทำให้ไฟล์เหมือน..anythingหรือ...anythingอื่น ๆ - stackoverflow.com/a/31438355/2351568มี regex ที่ถูกต้องสำหรับปัญหานี้ || แต่อย่างไรก็ตามการใช้shopt -s dotglobยังคงเป็นทางออกที่ดีกว่า!
DJCrashdummy

@DJCrashdummy น่าเสียดายที่ฉันไม่เข้าใจว่าทำไมคุณถึงเขียนความสนใจของคุณ ท้ายที่สุดโซลูชันของฉันคำนึงถึงกรณีที่คุณเขียน ขอแสดงความนับถือ
simhumileco

ขออภัยข้อความผิด! - ปัญหาที่เกิดขึ้นกับคำตอบของคุณคือมันจะพิจารณา.และ..(ซึ่งเทียบเท่ากับโฟลเดอร์ปัจจุบันและโฟลเดอร์ที่มี) || แต่ยังคงคำตอบในลิงค์อธิบายเพิ่มเติมและให้การแก้ปัญหา
DJCrashdummy

2

โปรดทราบว่ามีเคล็ดลับบรรทัดคำสั่ง (ทำงานอย่างน้อยsh , bashและksh ): เพียงต่อท้ายไดเรกทอรีจากด้วยเครื่องหมายทับ นี้จะเทเนื้อหาของจากไดเรกทอรีเข้าไปในการไดเรกทอรี (แดกดันฉันได้เรียนรู้แรกที่เกี่ยวกับเคล็ดลับนี้เมื่อใช้ rsync )

ตัวอย่าง:

/tmp$ mkdir test_dir1
/tmp$ cd test_dir1/
/tmp/test_dir1$ touch aa
/tmp/test_dir1$ touch .bb
/tmp/test_dir1$ cd ..
/tmp$ mkdir test_dir2

/tmp$ cp -r test_dir1/* test_dir2
/tmp$ ls -1a test_dir2
.
..
aa

/tmp$ cp -r test_dir1/ test_dir2
/tmp$ ls -1a test_dir2
.
..
.bb
aa

2

ฉันมาที่นี่เพื่อหาวิธีแก้ปัญหาแบบเดียวกันกับ Googled จากนั้นฉันก็รู้ว่าการค้นหาทำได้ง่าย ข้อดีมันไม่ได้ขึ้นอยู่กับเชลล์หรือยูทิลิตี้พิเศษที่อาจไม่ได้ติดตั้ง

find /etc/skel/ -mindepth 1 -exec cp -r {} /home/username/ \;

ฉันลองใช้เคล็ดลับด้วยการต่อท้ายเฉือน แต่นั่นไม่ได้ผลสำหรับฉัน


2

โซลูชันของฉันสำหรับปัญหานี้เมื่อฉันต้องคัดลอกไฟล์ทั้งหมด (รวมถึง.ไฟล์) ไปยังไดเรกทอรีเป้าหมายที่มีสิทธิ์คือ: (เขียนทับหากมีอยู่แล้ว)

yes | cp -rvp /source/directory /destination/directory/

yesมีไว้สำหรับเขียนทับไฟล์ปลายทางโดยอัตโนมัติ, rเรียกซ้ำ, vverbose, pสงวนสิทธิ์

ขอให้สังเกตว่าเส้นทางต้นทางไม่ได้ลงท้ายด้วย/ (ดังนั้นไฟล์ / ไดเรกทอรีและไฟล์ทั้งหมดจะถูกคัดลอก)

ไดเรกทอรีปลายทางลงท้ายด้วย/ขณะที่เรากำลังวางเนื้อหาของโฟลเดอร์ต้นทางไปยังปลายทางโดยรวม


1

ฉันได้เห็นว่า cp ไม่ได้คัดลอกไฟล์ที่ซ่อนอยู่เสมอและหากคุณต้องการคำสั่งที่ดูเหมือนว่าจะทำงานในทุกภาษา linux / unix คุณควรลองใช้:

cd /etc/skel
find | cpio -pdumv /home/user

-2

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


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