ฉันจะคัดลอกไฟล์ที่ชื่อขึ้นต้นด้วยจุดได้อย่างไร


23

ฉันกำลังพยายามคัดลอกไฟล์ทั้งหมดภายใต้ไดเรกทอรี A ไปยังไดเรกทอรี B ไฟล์ทั้งหมดภายใต้ไดเรกทอรี A เริ่มต้นด้วยจุดตัวอย่างเช่น:

A/.a
A/.b
A/.c

ซึ่งฉันพบว่าถ้าฉันใช้: cp A/* Bได้รับข้อผิดพลาด:

cp: cannot stat 'A/*': no such file or directory

ดูเหมือนว่าไม่มีตัวเลือกสำหรับ cp เช่น ls เพื่อจัดการกับรายการที่เริ่มต้นด้วยจุดทุกคนมีความคิดวิธีการแก้ไขหรือไม่

คำตอบ:


34

เหตุผลก็เพราะค่ะ bash, * ไม่รวมไฟล์ที่ขึ้นต้นด้วยจุด ( . )

คุณสามารถเรียกใช้

cp A/.* B

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

หรือถ้าคุณต้องการคัดลอกไฟล์ dot และไฟล์ปกติเข้าด้วยกันให้เรียกใช้

cp A/.* A/* B

คุณสามารถวิ่งได้

shopt -s dotglob
cp A/* B

ซึ่งจะทำงานใน bash, แต่ไม่ sh.

และถ้าคุณไม่รังเกียจที่จะคัดลอกไดเรกทอรีย่อยด้วยนี่ก็เป็นวิธีที่ง่ายที่สุด

cp -R A/ B

เคล็ดลับ: หากสัญลักษณ์แทนไม่ทำงานตามที่คุณคาดหวังให้ลองเรียกใช้ด้วยเสียงสะท้อนเช่น

$ echo A/*
A/file1 A/file2

$ echo A/.*
A/. A/.. A/.hidden1 A/.hidden2

$ echo A/.* A/*
A/. A/.. A/.hidden1 A/.hidden2 A/file1 A/file2

$ shopt -s dotglob
$ echo A/*
A/file1 A/file2 A/.hidden1 A/.hidden2

นั่นเป็นเพียงปัญหาถ้าคุณใช้ -r. ไม่มี -rมันจะข้ามไดเรกทอรี
Mikel

และตัวอย่างที่ฉันใช้ -R ควรทำงานได้ดีเช่นกัน หากคุณคิดว่ามันผิดโปรดอธิบายว่าทำไม
Mikel

7

หากทุบตีคุณสามารถตั้งค่า dotglob ก่อนที่คุณจะคัดลอก

shopt -s dotglob
cp A/* /destination

หรือภาษาโปรแกรม

$ ruby -rfileutils -e  'Dir[".*"].each {|x| FileUtils.copy(x,"/destination") if File.file?x}'

หากคุณไม่ต้องการตั้งค่า dotglob เพียง

cp A/.* /destination 2>/dev/null

การใช้ dotglob OP จะทำการคัดลอกไฟล์ที่ไม่ได้ซ่อนไว้ทั้งหมดซึ่งไม่ใช่สิ่งที่เขาต้องการ
peoro

@peoro คุณควรอ่านคำถามอีกครั้ง ไฟล์ทั้งหมดใน A ถูกซ่อนไว้ เขาต้องการคัดลอกสิ่งนั้น

5

สิ่งที่คุณกำลังมองหานั้นอยู่ในแนวของ

cp A/.??* B/

สิ่งนี้จะตรงกับ dotfiles ทั้งหมด แต่ไม่ใช่ "." หรือ "..". โซลูชันข้างต้นส่วนใหญ่ใช้ได้ดีตราบใดที่คุณไม่ได้ทำงานแบบวนซ้ำ แต่ทันทีที่คุณต้องการทำสิ่งที่ชอบ:

cp -R A/.??* B/

โดยไม่ละเว้น ".. " คุณจะคัดลอกทุกสิ่งจากไดเรกทอรีหลักลงรวมถึง non-dotfiles


1
สิ่งนี้จะพลาดจุดไฟล์ที่เป็นอักขระตัวเดียว .a หรือ .x. รูปแบบการวนรอบที่สั้นที่สุดที่ฉันพบว่าตรงกับไฟล์จุดทุกจุดยกเว้น . และ .. คือ .[^.]*.
pavon

2

ฉันลองต่อไปนี้และใช้งานได้ดี ...

cp A/.* B/

2
สิ่งนี้จะผ่านไป A/. และ A/.. เป็นพารามิเตอร์ไป cpซึ่งอาจเป็นปัญหาในกรณีที่ OP จำเป็นต้องคัดลอกไดเรกทอรีด้วย cp -r )
peoro

2

นั่นไม่ใช่ cp 's ความผิด มันทุบตี: ทุบตีขยาย * ในทุกสิ่งที่ไม่ซ่อนอยู่ (เช่น: ไม่ใช่เริ่มต้นด้วย . ) ไฟล์

Bash จะขยายตัว .* (ดังนั้น A/.*ในกรณีของคุณ) กับไฟล์ทั้งหมดที่เริ่มต้นด้วย .แต่โชคร้ายก็ยังรวมถึง . และ .. (ไดเรกทอรีปัจจุบันและไดเรกทอรีหลัก) ซึ่งคุณอาจจะต้องการข้าม (โปรดทราบว่าเชลล์อื่น ๆ เช่น zsh จะไม่รวมพวกเขาและ IIRC ก็ทุบตีหลังจากตั้งค่าตัวเลือกบางอย่าง)

ทางออกที่ง่ายอาจเป็นการลบ . และ .. จากไฟล์ที่จับคู่โดย .*ในแบบแฮ็ค (มาก) เช่นนี้

cp $( for F in A/.*; do echo $F | grep -v "^\.*$"; done ) B

หรืออันนี้ (อาจสะอาดกว่า: มันใช้ find เพื่อค้นหาไฟล์ที่จะคัดลอก):

cp $( find A -maxdepth 1 -mindepth 1 -name ".*" ) B

แต่คุณอาจจะพบโซลูชันที่สะอาดกว่า


ทำไมคุณควรใช้ for loop จากนั้นสร้างพิเศษ grep ดำเนินการเพียงเพื่อทำงานเช่นนี้ cp A/.* ? cp จะเพิกเฉยต่อ "." และไดเรกทอรี ".. "

1

หากพวกเขาเริ่มต้นด้วยจุดเพียงแค่ใช้ A/.*:

[holt@Michaela test]$ cp A/* B
cp: cannot stat `A/*': No such file or directory

[holt@Michaela test]$ cp A/.* B
cp: omitting directory `A/.'
cp: omitting directory `A/..'
[holt@Michaela test]$ ls -al B
total 8
drwxrwxr-x. 2 holt holt 4096 2011-03-31 16:57 .
drwxrwxr-x. 4 holt holt 4096 2011-03-31 16:57 ..
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .a
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .b
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .c

หวังว่านี่จะช่วยได้!


1

คุณสามารถใช้สคริปต์นี้

IFS = $ '\ n'; สำหรับการกระทำใน $ (ค้นหา A -d 1); ทำ cp -R "$ act" B; เสร็จแล้ว


0

สำเนา:

cp A/.* B

รายการ:

ls -l A/.*

รายการไฟล์ที่ไม่มีไดเรกทอรีจากมากไปน้อย:

ls -ld A/.*

0

คุณต้องยกเว้น และ .. จากรายการไฟล์ที่ส่งไปยัง cp!

นี่คือความปลอดภัย:

ls -1d A/.[a-zA-Z]* | xargs -i cp -rp {} B

0

นี่เป็นเธรดเก่า ... แต่ฉันสามารถคัดลอกไฟล์ทั้งหมดได้เสมอ การรวมไฟล์ / โฟลเดอร์ที่ขึ้นต้นด้วย '.'

ตัวอย่างจะคัดลอกไฟล์และโฟลเดอร์ทั้งหมด:

cp -aup /root/.* / backup / root /

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