Tạo một thư mục Hình ảnh trực tuyến bên trong tất cả các thư mục đệ quy


9

Tôi có một loạt các thư mục và tôi muốn lặp qua tất cả các thư mục đó và trong mỗi thư mục tạo một thư mục khác có tên "Ảnh"

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

Tôi muốn có:

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

Câu trả lời:


8

Từ thư mục ngay phía trên F1 chạy tập lệnh này:

Mục đích của kịch bản là để tránh việc có các thư mục ảnh dư thừa được tạo trong các thư mục ảnh.

Ngoài ra, nó được thiết kế để ngăn chặn việc vô tình chạy nó từ một vị trí sai, chẳng hạn như thư mục gốc của người dùng, trong khi nó sẽ không nhìn thấy F1thư mục và tạo nhầm hàng trăm thư mục ảnh trong các cung điện sai.

Ngoài ra, ý định của tôi là tạo ra một kịch bản dễ theo dõi để người dùng có thể tùy chỉnh nó.

#!/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)

Tập lệnh được cập nhật:

  • Thay đổi chữ thường ptrong photochữ hoa.
  • Đã thêm hỗ trợ cho tên tệp không đứng (với các đề xuất từ ​​Terdon).

1
Tôi chắc chắn sẽ tránh phân tích ls , nó có thể thất bại theo những cách khác thường. Tôi nghĩ rằng những câu trả lời tránh điều này có lẽ an toàn hơn.
Arronical

3
@Arronical lskhông được phân tích cú pháp. Đó chỉ là phản hồi cho người dùng ... hiển thị những gì đang xảy ra. Giống như dòng chữ "Đây là một thư mục ảnh". Nó cho người dùng biết tại sao nó không tạo một thư mục ở đó.
LD James

1
Tôi đã nghĩ rằng đó có thể là trường hợp, vì tôi không thể thấy bất cứ điều gì được thực hiện với nó. Trong trường hợp đó, tôi rút lại nhận xét của mình và bỏ qua :)
Arronical

find -type d F1, có lẽ?
Olivier Grégoire

Lưu ý rằng điều này sẽ thất bại nếu có một tệp (và không phải là thư mục) được gọi $i/Photo, nhưng OP không chỉ định những gì nên được thực hiện trong trường hợp đó. Nó cũng sẽ thất bại trong trường hợp không thể thừa nhận, trong đó một trong những $is có chứa một dòng mới.
terdon

24

Bạn có thể đạt được nó bằng một findcuộc gọi duy nhất .

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

Phần -name 'Photo' -prune -oyêu cầu không lặp lại các thư mục hiện có (và mới được tạo) Photo: Nếu tệp tìm thấy (hoặc thư mục) có tên Photo, dừng xử lý nó ( -prune). Trong trường hợp khác ( -o), tiếp tục với thư mục ( -type d) và thực thi ( -exec) lệnh.


ah tốt đẹp, tôi đã thử nó theo cách đó và tôi thấy từ câu trả lời của bạn rằng tôi đã sai ở đâu :)
Zanna

@Zanna -prune? :) Vâng, nó khá phản trực giác nhưng đáng để học hỏi.
Melebius

Nó sẽ dừng tạo thư mục 'Ảnh' nếu tệp có tên 'Ảnh' tồn tại?
Anwar

3
@Anwar Phiên bản hiện tại sẽ. Có một vùng màu xám trong yêu cầu. :) Bạn có thể thay đổi điều này bằng cách chỉ định -type dcùng với -name 'Photo'trước -prune.
Melebius

2
@Anwar Ở cái nhìn thứ hai, nó sẽ không có ý nghĩa. Bạn không thể tạo một thư mục có cùng tên với một tệp thông thường trong cùng một thư mục. Và findsẽ tiếp tục với các thư mục khác (bao gồm cả các thư mục con của thư mục đó, nếu bạn đang yêu cầu điều đó).
Melebius

9

Bạn có thể chuyển findkết quả cho whilethay vì vì forcách này sẽ không bị hỏng nếu tên tệp có khoảng trắng

Đầu tiên cd vào thư mục F1, sau đó làm:

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

Nếu thư mục tồn tại, mkdirsẽ từ chối tạo nó, vì vậy không có vấn đề gì ở đó ...

Nếu tên thư mục của bạn có thể chứa dòng mới hoặc sự kỳ lạ khác, hãy sử dụng tên này có thể xử lý tên tùy ý:

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

Cảm ơn @terdon đã giúp đỡ về việc này :)


Nếu F1thư mục của op là ~user/Pictures, di chuyển đến thư mục mẹ và chạy dòng sẽ đặt một Photothư mục trong mỗi thư mục trong không gian của anh ta, có thể là hàng ngàn. Cân nhắc thêm phần F1như một phần của dấu phẩy để tránh một lỗi dễ mắc phải. Theo cách đó, nếu nó vô tình chạy từ sai vị trí, nó sẽ không tạo thư mục.
LD James

ah yeah tôi thực sự không chắc chắn về cấu trúc thư mục của họ. Tôi đề nghị làm điều đó từ F1thay vào đó, chỉnh sửa @LDJames
Zanna

5

Python với os.walkcó thể làm điều đó khá dễ dàng và chỉ trong một vài dòng mã

$ 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

Giải trình

Điều chúng ta đang xử lý là lệnh này: python -c 'import os; [os.mkdir (r + "/ Pictures") cho r, d, f trong os.walk (".")]'

Ở đây chúng ta chỉ cần gọi trình thông dịch python với -ccờ để chỉ định lệnh chúng ta đưa ra trong dấu ngoặc đơn. os.walk()Hàm cho phép chúng tôi đệ quy từng bước qua tất cả các thư mục con và với mỗi thư mục con (được đại diện bởi r), chúng tôi tạo thư mục Ảnh thông qua os.mkdir()chức năng. r+"/Pictures"chỉ là một thao tác chuỗi đơn giản để nối chuỗi thư mục con và chuỗi "/ Pictures" lại với nhau để tạo thành một đường dẫn

Thay thế "/ Ảnh" bằng "/ Ảnh" để phù hợp với yêu cầu của bạn


4

Nếu bạn đang sử dụng bash, bạn chỉ cần chạy:

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

Các globstarlàm cho lựa chọn **phù hợp "tất cả các file và 0 hoặc nhiều thư mục và thư mục con". Nói cách khác, nó phù hợp với mọi thứ đệ quy. Bởi vì /ở cuối, **/sẽ phù hợp với tất cả các thư mục và thư mục con (không có tệp). Do đó, ý $dchí lặp đi lặp lại trên tất cả các thư mục trong thư mục hiện tại và thư mục con của chúng và thư mục Photossẽ được tạo trong mỗi thư mục đó.

Các -plá cờ của mkdirphương tiện:

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

Ở đây, tôi chỉ sử dụng nó để chặn thông báo lỗi nếu thư mục đích đã tồn tại. Loại bỏ nó nếu bạn muốn xem các lỗi.

Lưu ý rằng điều này sẽ không tạo được Photothư mục con trong thư mục đích chứa tệp có tên Ảnh. Bạn chưa chỉ định những gì nên được thực hiện trong những trường hợp đó và tất cả các câu trả lời khác được đăng cho đến nay cũng có giới hạn này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.