วิธีคัดลอกไฟล์ (เริ่มต้นด้วยจุด) ที่ซ่อนอยู่และไดเรกทอรีย่อยใน linux?


10

วิธีคัดลอกไฟล์ที่ซ่อนอยู่และไดเรกทอรีย่อยที่ซ่อนอยู่ (ไฟล์ที่ขึ้นต้นด้วยจุด) ในโฟลเดอร์ A ไปยังโฟลเดอร์ B เช่นถ้าฉันมีโครงสร้างนี้:

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

ฉันต้องการคัดลอกไปที่ B เพียงไฟล์ที่ซ่อนและไดเรกทอรีย่อยที่ซ่อนอยู่ใน A:

B/.a
B/.b/
B/.b/somefile
B/.b/.c

ผมได้พยายามแล้วคำสั่งนี้: cp A/.* Bจากคำถาม superuser อื่น ๆ อย่างไรก็ตามมันไม่ได้คัดลอกไดเรกทอรีย่อย ลองcp -r A/.* Bแล้ว แต่มันก็อปปี้.ดังนั้นฉันจึงลงท้ายด้วยสำเนาที่แน่นอนของ A (รวมถึงไฟล์ปกติ) ความช่วยเหลือใด ๆ ที่ชื่นชม

คำตอบ:


16

ตราบใดที่คุณกำลังมองหาไฟล์และโฟลเดอร์ที่ซ่อนอยู่ที่ระดับ A และไม่ต้องการเช่น

A/b/.hidden

หากต้องการคัดลอกคุณควรใช้สิ่งนี้:

cp -r A/.[^.]* B

โดยทั่วไปหมายถึงการคัดลอกสิ่งที่เริ่มต้นด้วย a .และจากนั้นอักขระอื่นใดนอกเหนือจาก.นั้นจะกรอง.และ..

แก้ไข: ลบ -p ออกจากคำสั่ง cp เนื่องจาก Asker ไม่ได้ระบุว่าเขาต้องการรักษาความเป็นเจ้าของวันที่ ฯลฯ


สิ่งนี้ใช้ได้กับตัวอย่างไฟล์และชื่อไดเรกทอรีที่ระบุในคำถาม แต่ข้อความของคำถามระบุว่า“ ไฟล์ที่ซ่อนอยู่และไดเรกทอรีย่อยที่ซ่อนอยู่ (ชื่อที่ขึ้นต้นด้วยจุด)” และคำตอบนี้จะไม่พบไฟล์และไดเรกทอรีที่ชื่อขึ้นต้นด้วยสองจุด; เช่น..c.
Scott

นั่นเป็นกรณีที่ค่อนข้างขอบ แต่ความกังวลที่ถูกต้องตามกฎหมายไม่มีใครน้อย ฉันไม่ได้คิดอย่างนั้น คุณสามารถอธิบายว่าโดยการเปลี่ยนไปแต่แล้วคุณจะคิดถึงแฟ้มที่ลงท้ายด้วย.*[^.] .ฉันคิดว่าคุณจะต้องขยายความจริง ๆ ไปทุกกรณี
Omnipresence

4

ปัญหากับการA/.*เป็นว่ามีไดเรกทอรี.ในAซึ่งยังตรงกับรูปแบบ

คุณสามารถเปิดรูปแบบ glob แบบขยายและใช้สิ่งต่อไปนี้:

shopt -s extglob
cp -r A/.!(?(.)) B    

มันจับคู่ไฟล์ที่มีชื่อขึ้นต้นด้วยจุดและอักขระตัวที่สองไม่ใช่จุดหรือไม่มีอะไร (? (.) ตรงกับไม่มีอะไรเลยหรือจุด! (... ) ขัดแย้งกับมันนั่นคือ! (? (.)) จับคู่ทุกอย่างอื่น กว่าอะไรหรือจุด)


+1 สำหรับคำตอบที่ถูกต้อง โปรดทราบว่า.!(@(|.))(AFAICT) เทียบเท่ากับด้านบน (IMNSHO) ที่ชัดเจนขึ้นเล็กน้อยและมีความยาวเพียงหนึ่งตัวอักษร
สกอตต์

3

สำหรับกรณีเช่นนี้ขอแนะนำให้ใช้findแทนcpเช่นนี้:

find A/ -type f -maxdepth 1 -name '.*' -exec cp -p {} B/ \;

ไวยากรณ์พื้นฐานแยกย่อยดังนี้:

  • find A/ -type f: findรายการในไดเรกทอรีA/ที่มีประเภทเป็นไฟล์ (แทนที่จะเป็นไดเรกทอรี) ...
  • -maxdepth 1 -name '.*': ในการนี้สำหรับmaxdepth1 ไดเรกทอรีและซึ่งเริ่มต้นด้วยname.
  • -exec cp -p {} B/ \;: และเมื่อไฟล์เหล่านี้จะพบคำสั่งที่มีธงที่จะรักษาวัน / ครั้งจากแหล่งที่มา ( ) ไปยังปลายทางของexeccp-p{}B/

ฉันชอบใช้maxdepthเพื่อเพิ่มเลเยอร์ของการควบคุมดังนั้นฉันจึงไม่ได้ตั้งใจคัดลอกระบบไฟล์ทั้งหมด แต่โปรดลบออกอย่างนั้น


0
 for item in `find A -type d | grep -E "\."` ; do cp -r $item B ; done
  • find A -type d จัดทำรายการแบบเรียกซ้ำภายใน A ที่มีไดเร็กทอรีเท่านั้น
  • grep -E "\." กรองไดเรกทอรีด้วยจุด (เช่น: ไดเรกทอรีที่ซ่อนอยู่)
  • อ็อพชัน -E ต้องการที่นี่เนื่องจากไม่ได้หมายความว่า "ไดเร็กทอรีปัจจุบัน" เช่นกัน
  • แบ็กสแลชคือการหลีกเลี่ยงความหมายภายใต้ regexp ของ "ตัวละครใด ๆ "
  • cp -r เพื่อคัดลอกซ้ำ

ฉันได้สร้างโครงสร้างไฟล์และโฟลเดอร์สำหรับ A และดำเนินการคำสั่งใน Git Bash (ตอนนี้ฉันยังไม่ได้ใช้ linux เลย) และมันก็ใช้ได้


ตัวแบ่งนี้หากไฟล์มีช่องว่างหรืออักขระพิเศษในชื่อหรือพา ธ
slhck

ขอบคุณที่สังเกต :) จริง ๆ แล้วฉัน จำกัด เฉพาะ "test case" โดย @gaboroncancio หากคุณสามารถให้แบตเตอรี่ทดสอบอื่น ๆ ให้ฉันฉันอาจลองปรับปรุงมัน (แน่นอนถ้าคุณต้องการให้ปรับปรุงด้วยตัวเองไม่ว่าจะเป็นการแก้ไขคำตอบนี้หรือสร้างคำตอบใหม่)
malarres

คุณก็สามารถใส่ dotfiles ในโฟลเดอร์ที่เรียกว่าแล้วมันจะทำหน้าที่โดยไม่คาดคิดเพราะมันจะขยายตัวออกไปA B cp -r A B/.dotfile Bคำแนะนำทั่วไปไม่ได้แยกวิเคราะห์findหรือlsส่งออกเลย หากคุณใช้findคุณควรใช้ตัวเลือกของตัวเองสำหรับการกรองมากกว่าgrepและถ้าคุณไพพ์findเอาท์พุทที่อื่นให้ใช้-print0หรือเรียกคำสั่งที่คุณต้องการโดยตรง ดูคู่มือfind
slhck

โดยทั่วไปเมื่อทำงานกับไฟล์การใช้ shell globs อย่างปลอดภัยที่สุดเท่าที่อธิบายไว้ในคำตอบอื่น ๆ (แม้ว่าจะต้องextglobตั้งค่าบ่อยครั้ง)
slhck

ขอบคุณสำหรับลิงค์ ปล่อยให้การfindแยกวิเคราะห์แล้ว
malarres

0

เป็นอีกทางเลือกหนึ่งที่คุณสามารถใช้คำสั่งนี้ถ้าอักขระตัวที่สองคือตัวอักษรและตัวเลข ( แหล่งที่มา ):

cp -r A/.[a-zA-Z0-9]* B

สิ่งนี้ใช้ได้กับตัวอย่างไฟล์และชื่อไดเรกทอรีที่ระบุในคำถาม แต่ข้อความของคำถามระบุว่า“ ไฟล์ที่ซ่อนอยู่และไดเรกทอรีย่อยที่ซ่อนอยู่ (ชื่อที่ขึ้นต้นด้วยจุด)” และคำตอบนี้จะไม่พบไฟล์และไดเรกทอรีที่ชื่อขึ้นต้นด้วย จุดและอักขระพิเศษ; เช่นหรือ.@foo ..c
Scott

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