ฉันจะสร้างไดเรกทอรีในไดเรกทอรีย่อยทั้งหมดได้อย่างไร


34

สมมติว่าฉันมีโครงสร้างไดเรกทอรีเช่นนี้

$ [~ / ฝึก] ls
เอบีซีดี/

ตอนนี้ฉันต้องการสร้างไดเรกทอรีtmp1ในไดเรกทอรีย่อยทั้งหมดpracticeและฉันทำสิ่งนี้:

$ [~ / ฝึก] mkdir * / tmp1
mkdir: ไม่สามารถสร้างไดเรกทอรี `* / tmp1 ': ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว

จากนั้นฉันลอง-pสวิตช์และจบด้วยไดเรกทอรีที่*มีไดเรกทอรีย่อยtmp1

$ [~ / ฝึก] mkdir -p * / tmp1

$ [~ / ฝึก] ls
*/ เอบีซีดี/

ฉันรู้ว่าการใช้-pสวิตช์คือการสร้างไดเรกทอรีที่ไม่มีอยู่หลายรายการ ฉันแค่คิดว่ามันอาจช่วย

ฉันจะสร้างtmp1ในไดเรกทอรีย่อยทั้งหมดได้ในครั้งเดียวได้อย่างไร

หากสามารถทำได้ฉันจะขยายไปยังการสร้าง\tmp1, \tmp2, \tmp3ใน\a, \bและ\cในครั้งเดียว?

แก้ไข:ฉันพลาดการกล่าวขวัญว่าไดเรกทอรีที่ไม่จำเป็นต้องเป็นที่เรียบง่ายและในการสั่งซื้อเช่นa, b, cฯลฯ และไดเรกทอรีที่จะถูกสร้างขึ้นไม่จำเป็นต้องเหมือน,tmp1tmp2

$ [~ / ฝึก] ls
สุนัข / แมว / หนู /

ในพวกเขาฉันต้องการมีบางอย่าง

$ [~ / ฝึก] ls *
หมา:
สีแดงสีฟ้า/

แมว:
สีแดงสีฟ้า/

หนู:
สีแดงสีฟ้า/

1
ด้วยคำตอบของคริสโตเฟอร์คุณควรชี้แจงว่า "สร้าง \ tmp1, \ tmp2, \ tmp3 ใน \ a, \ b และ \ c" ควรส่งผลให้ไดเรกทอรีย่อยทั้งหมด 3 หรือ 9 รายการ
จัดการ

@ การทำงาน: นั่นเป็นจุดที่ดี มันควรสร้าง 9 ไดเรกทอรีย่อย
Animesh

นี้ช่วยฉันในการแก้ปัญหาพื้นที่ในชื่อของไดเรกทอรี sudo find ./ -depth -type d -exec echo '"{} / RCS"' \;

คำตอบ:


44

ด้วยglobs :

for dir in */; do mkdir -- "$dir/tmp1"; done

บันทึก

  • ฉันปฏิบัติต่อ dirs เท่านั้น (รวมถึง symlinks to dirs) ด้วยแฮ็คเล็ก ๆ ของการใช้*/เป็น glob
  • หากคุณต้องการสร้างหลายตำบลพร้อมกัน:

    for dir in */; do mkdir -- "$dir"/{tmp1,foo,bar,qux}; done


ฉันสามารถfor i in */; do mkdir "$i/itemone" "$i/itemtwo"; doneใช้ชื่อไดเรกทอรีหลายชื่อเรียงตามลำดับได้หรือไม่
Animesh

ฉันทดสอบมันและมันเป็นไปได้มาก ขอบคุณ
Animesh

ดูโพสต์ที่แก้ไขแล้วของฉัน
Gilles Quenot

1
การขยายตัวของรั้งไม่ได้ดำเนินการในสตริงที่ยกมา
จัดการ

ใช่ขอบคุณโพสต์แก้ไขโดย Stephane Chazelas ตาม ...
Gilles Quenot


10

ด้วย GNU หรือ BSD * ค้นหา:

find -mindepth 1 -maxdepth 1 -type d -exec mkdir {}/newdir \;

หรือใช้การขยายพารามิเตอร์:

dirs=(*/)
mkdir -- "${dirs[@]/%/newdir}"

* รวม OS X


2
ด้วยไวยากรณ์ค้นหามาตรฐาน:find . -name . -o -prune -type d -exec sh -c 'exec mkdir "$1/newdir"' sh {} \;
Stéphane Chazelas

1
นอกจากนี้ยังสังเกตเห็นความแตกต่างระหว่างโซลูชันสองรายการ: รายการแรกมีไดเรกทอรีที่ซ่อนอยู่ส่วนที่สองจะเพิ่มไดเรกทอรีใหม่ในไดเรกทอรีที่ลิงก์โดย symlink ใด ๆ ในไดเรกทอรีปัจจุบัน
Stéphane Chazelas

6

ปิดหัวข้อเนื่องจากคุณพูดถึงbashแต่สำหรับระเบียนด้วย zsh คุณต้องทำ:

dirs=(*(/))
mkdir -- $^dirs/tmp1

$^varเปิดใช้การขยายแบบคล้ายรั้งสำหรับการขยายตัวของอาร์เรย์ มันชวนให้นึกถึงrcของ^ผู้ประกอบการและrc(หรืออนุพันธ์es) ที่คุณต้องการเขียน:

dirs=(*/)
mkdir -- $dirs^tmp1

อย่างไรก็ตามหมายเหตุ (และวิธีนี้ใช้กับโซลูชัน bash ที่กำหนดไว้ที่นี่) ซึ่งในโซลูชัน rc dirsจะมีลิงก์สัญลักษณ์ไปยังไดเรกทอรีด้วย ในโซลูชัน zsh ให้เปลี่ยน*(/)เป็น*(-/)ถ้าคุณต้องการรวม symlinks ไปยังไดเรกทอรี


+1 สำหรับประเด็นเกี่ยวกับ symlinks ของคุณ! พฤติกรรมนี้อาจต้องการ แต่การร้องเรียนของ mkdir เกี่ยวกับการสร้างไดเรกทอรีที่ซ้ำกันสามารถระงับได้ด้วยการ-pตั้งค่าสถานะ
kojiro

4

พกพาไปที่ไดเรกทอรีหลัก:

for d in */; do mkdir "$d/red" "$d/blue"; done

เพิ่ม--หลังจากที่ถ้าคุณอาจมีไดเรกทอรีที่มีชื่อเริ่มต้นด้วยmkdir-

ใน zsh คุณสามารถทำได้ด้วยคำสั่งเดียวด้วยตัวระบุe glob :

mkdir *(/e\''REPLY=($REPLY/{red,blue})'\')

แต่มันเร็วกว่าที่จะพิมพ์คำสั่งนี้เป็นสองคำสั่ง:

d=(*(/)); mkdir $^d/{red,blue}

1
เกี่ยวกับเว็บไซต์ที่มีขึ้นเพื่อเป็นข้อมูลอ้างอิงฉันอยากจะพูด " mkdir -- whateverและงด --ถ้าคุณตั้งใจสำหรับการขยายตัวของสิ่งที่จะต้องดำเนินการอาจจะเป็นตัวเลือกให้กับmkdirคำสั่ง." ไม่มีประเด็นที่จะละเว้น--ที่นี่ อาจไม่เป็นปัญหาในกรณีของ OP แต่เป็นปัญหาในกรณีทั่วไป ฉันคิดว่าเรามีหน้าที่สอนไวยากรณ์ที่ถูกต้องและปลอดภัยที่นี่
Stéphane Chazelas

@StephaneChazelas ในบริบทการเขียนสคริปต์ฉันมักจะใส่สิ่งที่จำเป็น--และคำพูดและคำเตือนไขมันใหญ่เมื่อสายใหม่ไม่ได้รับการสนับสนุน ในบริบทของบรรทัดคำสั่งฉันต้องการแสดงเวอร์ชันด่วนที่ใช้งานได้จริงก่อนและเวอร์ชันกระสุนเป็นส่วนเสริม
Gilles 'ดังนั้น - หยุดความชั่วร้าย'


1

รูปแบบของคำตอบของ sputnick ซึ่งหลีกเลี่ยงไฟล์ที่ไม่ใช่ไดเรกทอรี:

for x in *; do if [ -d "$x" ]; then mkdir "$x/tmp1"; fi; done

ฉันปฏิบัติต่อ dirs เท่านั้นนั่นคือ "เวทมนตร์ทั้งหมด ...
Gilles Quenot

เจ๋งเข้าใจแล้ว)
goldilocks

2
ไม่ควรจะเป็นอย่างนั้นif [ -d "$x" ];…?
kojiro

ใช่. ฉันไม่เคยมีช่องว่างในชื่อไฟล์และมีแนวโน้มที่จะลืมสิ่งที่ ...
Goldilocks

1

นี่เป็นสิ่งที่ดีจาก Unix Masters เก่า (ทดสอบบน FreeBSD 10.1) หากคุณต้องการควบคุมเวอร์ชัน (ด้วยการเช็คอิน RCS ล็อค: ci -l พร้อมความคิดเห็นสั้น ๆ ว่า ir: สำหรับการเปิดตัวครั้งแรก) ไฟล์ / etc / * config ของคุณ ใน ~ / .his / etc

sudo rsync -av /etc/ ~/.his
sudo find -d ~/.his/etc -type d -exec echo '{}/RCS' \; | xargs sudo mkdir -p
sudo find -d ~/.his/etc \! -name "RCS" | xargs sudo ci -l -mir -t-ir

ฉันล้มเหลวที่จะดูว่าคำตอบนี้ OP
Archemar

1

ควรจะเป็น \! ชื่อ "RCS" และทำงานได้ดีที่สุดในการเช็คอินครั้งแรก

sudo หา ~ / .his / etc \! - ชื่อ "RCS" -ls

sudo find -d ~ / .his / etc \! -name "RCS" | xargs sudo ci -l -mir -t-ir

อันสุดท้ายนี้ยังใช้งานได้ดีมากสำหรับ cjeck ในส่วนการกรองเนื้อหา RCS ทั้งหมดในชื่อไฟล์:

sudo find -d ~ / .his / etc -type f | grep -v RCS | xargs sudo ci -l -mir -t-ir


1

นี่เป็นความช่วยเหลือที่ดีสำหรับฉัน ฉันต้องการสร้างชุดของไดเรกทอรีย่อยในหลาย ๆ โฟลเดอร์และบางอย่างเช่น:

!/bin/sh

cd /dest/cont

for dir in */*/; do
    mkdir -p -- $dir/{FB,Video,Audio,proj};
done

ทำงานได้ดียกเว้นเมื่อพบช่องว่าง มีวิธีละเว้นช่องว่างใน*/*/ส่วนของการขัดแย้งหรือไม่

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