สร้างไดเรกทอรีซ้ำสำหรับตัวอักษรทั้งหมด


12

ฉันต้องการที่จะสร้างไดเรกทอรีในลักษณะดังกล่าวที่ฉันต้องการที่จะติดป้ายไดเรกทอรีที่จากไปa zภายในแต่ละไดเรกทอรีเหล่านี้ผมจำเป็นต้องสร้างไดเรกทอรีย่อยเพื่อให้พวกเขาได้รับการระบุว่าเป็นaa, abฯลฯ

ดังนั้นสำหรับตัวอย่างเช่นสำหรับไดเรกทอรีmไดเรกทอรีย่อยของฉันจะได้รับการระบุว่าเป็นma, ไม่เกินmbmz


3
คุณไม่ต้องการ mkdir แรกเพราะ -p กำลังสร้างไดเรกทอรีย่อยด้วย และคุณไม่ต้องการคำสั่ง cd ถ้าคุณใช้การยกเลิกเส้นทาง ไม่อย่างนั้นมันดีการทำงานตัวแปรที่ประกาศ ฯลฯ เวอร์ชันของ Michael Homer นั้นสั้นกว่าและอาจมีประสิทธิภาพที่ดีกว่า

1
ย้อนกลับไปในวันนี้มีรายการ terminfo มากกว่าและไม่มี bash {a..z} ไวยากรณ์ดังนั้นฉันจึงออกรายการ/usr/share/terminfoด้วย [az] และใช้ผลลัพธ์นั้น ลินุกซ์ค่อนข้างกระจัดกระจายในจำนวนนั้นเคยเป็นรายการสำหรับอักขระตัวพิมพ์ใหญ่และตัวพิมพ์เล็กทั้งหมดรวมถึงตัวเลข
แบบแผน

คำตอบ:


19

ลอง:

for x in {a..z} ; do mkdir -p $x/${x}{a..z} ; done

ทุบตีจะขยายXXX{a..z}ออกไปXXXa, XXXbและอื่น ๆ คุณไม่จำเป็นต้องมีวงใน

หลังจากนั้น:

$ ls
a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z
$ ls m
ma  mc  me  mg  mi  mk  mm  mo  mq  ms  mu  mw  my
mb  md  mf  mh  mj  ml  mn  mp  mr  mt  mv  mx  mz

7

ดังนั้นด้วยbashการขยายตัวของตัวอักษรงานนี้:

set {a..z}
for a do printf "./$a/$a%s\n" "$@"
done | xargs mkdir -p

และถ้าคุณพิมพ์ตัวอักษรเพียงครั้งเดียวในบรรทัดแรกแนวคิดเดียวกันควรพกพาไปยังเปลือกหอยใด ๆ มีวิธีอื่น ๆ ที่จะมาถึงที่บรรทัดที่กำหนดถ้าคุณไม่ต้องการพิมพ์เช่น:

seq -sP32P 97 123|dc
a b c d e f g h i j k l m n o p q r s t u v w x y z 

... เช่นอินสแตนซ์ทำงานในโลแคล ASCII ดังนั้นคุณสามารถทำset $(seq -sP32P 97 123|dc)หรือคำสั่งอื่น ๆ ที่จะทำให้คุณมี$IFSรายการของการขัดแย้งที่คุณต้องการแยกกัน แต่ฉันหมายความว่ามันอาจจะดีกว่าที่จะใช้bashสิ่งนั้นหรือพิมพ์มัน

อย่างไรก็ตามฉันคิดว่านั่นเป็นวิธีที่ฉันจะทำได้ถ้าเพียงเพราะมันเรียกใช้mkdirบ่อยเท่าที่จำเป็น

และเพื่อแสดงให้เห็นถึงวิธีการทำงานนี่เป็นข้อบกพร่องเล็กน้อยของชุดเล็ก:

sh -cx 'for n do printf "./$n/$n%s\n" "$@"; done|cat' -- arg1 arg2 arg3
+ for n in '"$@"'
+ printf './arg1/arg1%s\n' arg1 arg2 arg3
+ cat
+ for n in '"$@"'
+ printf './arg2/arg2%s\n' arg1 arg2 arg3
+ for n in '"$@"'
+ printf './arg3/arg3%s\n' arg1 arg2 arg3
./arg1/arg1arg1
./arg1/arg1arg2
./arg1/arg1arg3
./arg2/arg2arg1
./arg2/arg2arg2
./arg2/arg2arg3
./arg3/arg3arg1
./arg3/arg3arg2
./arg3/arg3arg3

ในขณะที่คุณสามารถดูforลูปเพียงครั้งเดียวต่อดัชนีพารามิเตอร์อาร์เรย์ตำแหน่งซึ่งผมนี่ตั้งโดยเพียงแค่การยื่นพารามิเตอร์ที่ภาวนาและข้างต้นด้วยsh set ${positionals}แต่printfได้รับอาร์เรย์เดียวกันในรายการอาร์กิวเมนต์สำหรับแต่ละการวนซ้ำและใช้สตริงการจัดรูปแบบกับอาร์กิวเมนต์แต่ละตัวดังนั้นคุณจะได้รับการเรียกซ้ำโดยไม่ต้องเรียกซ้ำ

และการเพิ่มdone|commandจะส่งกระแสข้อมูลทั้งหมดของforลูปไปยังไพพ์ในทางเดียวกันdone >fileจะสตรีมข้อมูลทั้งหมดลงในไฟล์ - เปิดและปิดไฟล์เอาต์พุตเพียงครั้งเดียวสำหรับการfor...doneสร้างทั้งหมด


3

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

for x in {a..z}
do
    mkdir -p /home/ramesh/$x
    cd /home/ramesh/$x
    for y in {a..z}
    do
        mkdir -p /home/ramesh/$x/$x$y
    done
done

+1 คำถามที่ดีและคำตอบที่ดี :)
Nidal

@ เครือข่ายฉันแน่ใจว่ามีวิธีแก้ปัญหาที่ดีกว่านี้ รอคำตอบจากผู้เชี่ยวชาญบางอย่างที่จะทำผลงานได้เป็นที่คล้ายกันเป็นคำตอบนี้ แต่จะมีลักษณะเย็นมาก :)
ราเมษ

การพูดอย่างเคร่งครัดไม่จำเป็นเมื่อคุณรู้ว่าค่าตัวแปรจะเป็นอย่างไร (และเป็นสตริงธรรมดา) แต่เป็นความคิดที่ดีที่จะใช้นิสัยในการอ้างอิงตัวแปรของคุณ คุณสามารถใช้/home/ramesh/"$x"/"$x$y", /home/ramesh/"$x/$x$y"หรือ"/home/ramesh/$x/$x$y"- พวกเขากำลังเทียบเท่าทั้งหมด
สกอตต์

1

ในPerl:

perl -MFile::Path=make_path -e '
    make_path(map { $l=$_; map { "$l/$l$_" } a..z } a..z)
'

File::PathPerl 5.001เป็นโมดูลหลักตั้งแต่

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