สร้างโฟลเดอร์“ ภาพถ่าย” ในไดเรกทอรีทั้งหมดซ้ำ


9

ฉันมีโฟลเดอร์มากมายและฉันต้องการวนซ้ำโฟลเดอร์เหล่านั้นทั้งหมดและในแต่ละโฟลเดอร์จะสร้างโฟลเดอร์อื่นที่ชื่อว่า "ภาพถ่าย"

F1
--F11
----F111
----F112
--F12

ฉันต้องการ:

F1
--Photo
--F11
----Photo
----F111
------Photo
----F112
------Photo
--F12
----Photo

คำตอบ:


8

จากไดเรกทอรีด้านบน F1 ใช้สคริปต์นี้:

วัตถุประสงค์ของสคริปต์คือการหลีกเลี่ยงการสร้างไดเรกทอรีรูปภาพซ้ำซ้อนภายใต้ไดเรกทอรีรูปภาพ

นอกจากนี้ยังได้รับการออกแบบมาเพื่อป้องกันการเรียกใช้โดยไม่ตั้งใจจากตำแหน่งที่ไม่ถูกต้องเช่นไดเรกทอรีรากของผู้ใช้ในขณะที่มันจะไม่เห็นF1ไดเรกทอรีและสร้างไดเรกทอรีรูปภาพนับร้อยในผิดที่ผิดพลาด

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

#!/bin/bash

while IFS= read -r -d '' i;
do
    if [[ ! -d $i/Photo ]]; then
        # Filter to skip folders named Photo
        thisfolder="$(echo $i | sed "s/.*\///")"
        if [[ ! $thisfolder == "Photo" ]]; then
            mkdir "$i/Photo"
        fi
    fi
done < <(find F1 -type d -print0)

อัปเดตสคริปต์:

  • การเปลี่ยนแปลงกรณีที่ต่ำกว่าpในphotoกรณีบน
  • เพิ่มการสนับสนุนสำหรับชื่อไฟล์ที่ไม่ใช่สแตนด์บาย (พร้อมคำแนะนำจาก Terdon)

1
ฉันหลีกเลี่ยงการแยกวิเคราะห์ lsแน่นอนมันอาจล้มเหลวในรูปแบบที่ผิดปกติ ฉันคิดว่าคำตอบที่หลีกเลี่ยงสิ่งนี้อาจปลอดภัยกว่า
59

3
@Arronical lsไม่ได้ถูกแยกวิเคราะห์ มันเป็นเพียงความคิดเห็นของผู้ใช้ ... แสดงสิ่งที่เกิดขึ้น เช่นเดียวกับคำว่า "นี่คือไดเรกทอรีรูปภาพ" เป็นการแจ้งให้ผู้ใช้ทราบว่าเหตุใดจึงไม่สร้างไดเรกทอรีที่นั่น
LD James

1
ฉันคิดว่าอาจเป็นกรณีนี้เพราะฉันไม่เห็นสิ่งที่ทำกับมัน ในกรณีนี้ฉันถอนความคิดเห็นของฉันและลดความชันลง :)
23416 Arronical

find -type d F1, อาจจะ?
Olivier Grégoire

โปรดทราบว่าสิ่งนี้จะล้มเหลวหากมีไฟล์ (และไม่ใช่ไดเรกทอรี) ที่เรียกว่า$i/Photoแต่ OP ไม่ได้ระบุสิ่งที่ควรทำในกรณีดังกล่าว นอกจากนี้ยังจะล้มเหลวในกรณีที่ไม่น่ายอมรับซึ่งหนึ่งในนั้น$iมีการขึ้นบรรทัดใหม่
terdon

24

คุณสามารถทำได้โดยใช้การfindโทรเพียงครั้งเดียว

find . -name 'Photo' -prune -o -type d -exec mkdir {}/Photo \;

ส่วน-name 'Photo' -prune -oบอกว่าจะไม่เรียกคืนไปยังPhotoไดเรกทอรี(และสร้างขึ้นใหม่) ที่มีอยู่: หากไฟล์ที่พบ (หรือไดเรกทอรี) มีชื่อPhotoให้หยุดการประมวลผล ( -prune) ในกรณีอื่น ( -o) ให้ดำเนินการต่อด้วยไดเรกทอรี ( -type d) และดำเนินการ ( -exec) คำสั่ง


อาดีฉันพยายามมันและวิธีการที่ผมเห็นจากคำตอบของคุณที่ผมจะผิด :)
Zanna

@ ซานน่า-prune? :) ใช่มันค่อนข้างจะเรียนรู้ได้ง่าย
Melebius

มันจะหยุดการสร้างโฟลเดอร์ 'Photo' หรือไม่หากมีไฟล์ชื่อ 'Photo' อยู่
อันวาร์

3
@Anwar เวอร์ชันปัจจุบันจะ มีข้อกำหนดโซนสีเทา :) คุณสามารถเปลี่ยนแปลงได้โดยการระบุ-type dด้วยกันก่อน-name 'Photo' -prune
Melebius

2
@Anwar เมื่อเห็นแวววาวครั้งที่สองมันก็ไม่สมเหตุสมผล คุณไม่สามารถสร้างโฟลเดอร์ที่มีชื่อเดียวกันกับไฟล์ปกติภายในโฟลเดอร์เดียวกัน และfindจะดำเนินการกับโฟลเดอร์อื่น ๆ (รวมถึงโฟลเดอร์ย่อยของโฟลเดอร์นั้นหากคุณต้องการสิ่งนั้น)
Melebius

9

คุณสามารถส่งfindผลลัพธ์ไปยังwhileแทนที่จะเป็นforวิธีนี้มันจะไม่แตกถ้าชื่อไฟล์มีช่องว่าง

cd แรกไปยังไดเรกทอรีF1จากนั้นทำ:

find -type d | while read dir ; do mkdir "$dir"/Photo ; done

หากไดเรกทอรีมีอยู่mkdirก็จะปฏิเสธที่จะสร้างมันจึงไม่มีปัญหา ...

หากชื่อไดเรกทอรีของคุณอาจมีการขึ้นบรรทัดใหม่หรือความแปลกที่แปลกใหม่อื่น ๆ ให้ใช้สิ่งนี้ซึ่งสามารถจัดการกับชื่อที่กำหนดเองได้:

find -type d -print0 | while IFS= read -r -d '' dir ; do mkdir "$dir"/Photo ; done

ขอบคุณ @terdon สำหรับความช่วยเหลือ :)


หากF1ไดเรกทอรีของ op คือการ~user/Picturesย้ายไปยังไดเรกทอรีหลักและเรียกใช้บรรทัดจะทำให้Photoไดเรกทอรีในทุกไดเรกทอรีในพื้นที่ของเขาซึ่งอาจเป็นพัน พิจารณาเพิ่มF1ส่วนหนึ่งของ commanline เพื่อหลีกเลี่ยงข้อผิดพลาดที่ทำง่าย ด้วยวิธีนี้หากเรียกใช้โดยไม่ตั้งใจจากสถานที่ที่ไม่ถูกต้องจะไม่สร้างไดเรกทอรี
LD James

ใช่แล้วจริง ๆ แล้วฉันไม่แน่ใจในโครงสร้างไดเรกทอรีของพวกเขา ฉันขอแนะนำให้ทำF1แทนการแก้ไข @LDJames
Zanna

5

งูหลามกับos.walkสามารถทำได้ค่อนข้างง่ายและเพียงไม่กี่บรรทัดของรหัส

$ mkdir dir_one dir_two
$ mkdir dir_two/dir_three
$ python -c 'import os;[os.mkdir(r + "/Pictures") for r,d,f in os.walk(".")]'                 
$ tree
.
├── dir_one
│   └── Pictures
├── dir_two
│   ├── dir_three
│   │   └── Pictures
│   └── Pictures
└── Pictures

คำอธิบาย

สิ่งที่เรากำลังจัดการคือคำสั่งนี้: python -c 'import os; [os.mkdir (r + "/ Pictures") สำหรับ r, d, f ใน os.walk (".")]'

ที่นี่เราเพียงแค่เรียก python interpreter พร้อม-cflag เพื่อระบุคำสั่งที่เราให้ไว้ในเครื่องหมายคำพูดเดี่ยว os.walk()ฟังก์ชั่นช่วยให้เราสามารถทำซ้ำขั้นตอนผ่านไดเรกทอรีย่อยทั้งหมดและสำหรับแต่ละไดเรกทอรีย่อย (แสดงโดยr) เราสร้างโฟลเดอร์รูปภาพผ่านos.mkdir()ฟังก์ชั่น r+"/Pictures"เป็นเพียงการจัดการสตริงง่ายๆในการเข้าร่วมสตริงไดเรกทอรีย่อยและสตริง "/ Pictures" ร่วมกันเพื่อสร้างเส้นทางเดียว

แทนที่ "/ Pictures" ด้วย "/ Photo" เพื่อให้เหมาะกับความต้องการของคุณ


4

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

shopt -s globstar
for d in **/; do mkdir -p "$d"/Photo; done

globstarตัวเลือกที่จะทำให้**การแข่งขัน "ไฟล์ทั้งหมดและ 0 หรือมากกว่าไดเรกทอรีและไดเรกทอรีย่อย" กล่าวอีกนัยหนึ่งมันตรงกับทุกสิ่งที่เกิดซ้ำ เนื่องจาก/ในตอนท้าย**/จะจับคู่ไดเรกทอรีและไดเรกทอรีย่อยทั้งหมด (ไม่มีไฟล์) ดังนั้นการ$dทำซ้ำจะข้ามไดเรกทอรีทั้งหมดในไดเรกทอรีปัจจุบันและไดเรกทอรีย่อยและPhotosไดเรกทอรีจะถูกสร้างขึ้นในแต่ละไดเรกทอรี

-pธงชาติmkdirหมายถึง:

  -p, --parents
          no error if existing, make parent directories as needed

ที่นี่ฉันแค่ใช้มันเพื่อระงับข้อความแสดงข้อผิดพลาดหากมีไดเรกทอรีเป้าหมายอยู่แล้ว ลบออกหากคุณต้องการดูข้อผิดพลาด

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

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