Buat folder "Foto" di dalam semua direktori secara rekursif

9

Saya memiliki banyak folder dan saya ingin mengulang semua folder itu dan di setiap folder membuat folder lain bernama "Foto"

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

Saya ingin memiliki:

F1
--Photo
--F11
----Photo
----F111
------Photo
----F112
------Photo
--F12
----Photo
OOzy Pal
sumber

Jawaban:

8

Dari direktori tepat di atas F1 jalankan skrip ini:

Tujuan dari skrip ini adalah untuk menghindari pembuatan direktori foto yang berlebihan di bawah direktori foto.

Juga, ini dirancang untuk mencegahnya menjalankannya secara tidak sengaja dari lokasi yang salah seperti direktori root pengguna, sedangkan direktori tersebut tidak akan melihat F1direktori dan secara keliru membuat ratusan direktori foto di istana yang salah.

Selain itu, niat saya adalah membuat skrip yang mudah diikuti sehingga pengguna dapat menyesuaikannya.

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

Skrip Diperbarui:

  • Mengubah huruf kecil pdalam photokasus atas.
  • Menambahkan dukungan untuk nama file yang tidak standar (dengan saran dari Terdon).
LD James
sumber
1
Saya pasti menghindari parsing ls , itu bisa gagal dengan cara yang tidak biasa. Saya pikir jawaban yang menghindari ini mungkin lebih aman.
Arronical
3
@Arronical lstidak diuraikan. Ini hanya umpan balik kepada pengguna ... yang menunjukkan apa yang terjadi. Sama seperti kata-kata "Ini adalah direktori foto". Ini memberi tahu pengguna mengapa tidak membuat direktori di sana.
LD James
1
Saya pikir itu mungkin terjadi, karena saya tidak bisa melihat apa pun dilakukan dengan itu. Dalam hal ini, saya menarik kembali komentar saya dan meluncur :)
Arronical
find -type d F1, mungkin?
Olivier Grégoire
Perhatikan bahwa ini akan gagal jika ada file (dan bukan direktori) yang dipanggil $i/Photo, tetapi OP belum menentukan apa yang harus dilakukan dalam kasus seperti itu. Ini juga akan gagal dalam, kasus tidak diakui, di mana salah satu dari $is berisi baris baru.
terdon
24

Anda dapat mencapainya menggunakan satu findpanggilan.

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

Bagian -name 'Photo' -prune -omemberitahu untuk tidak berulang ke Photodirektori yang ada (dan baru dibuat) : Jika file yang ditemukan (atau direktori) memiliki nama Photo, berhenti memprosesnya ( -prune). Dalam kasus lain ( -o), lanjutkan dengan direktori ( -type d) dan jalankan ( -exec) perintah.

Melebius
sumber
ah bagus, saya mencobanya seperti itu dan saya melihat dari jawaban Anda di mana saya salah :)
Zanna
@Zanna -prune? :) Ya, ini cukup kontra-intuitif tetapi layak dipelajari.
Melebius
Apakah akan berhenti membuat folder 'Foto' jika ada file bernama 'Foto'?
Anwar
3
@Anwar Versi saat ini akan. Ada zona abu-abu dalam persyaratan. :) Anda dapat mengubah ini dengan menentukan -type dbersama-sama dengan -name 'Photo'sebelum -prune.
Melebius
2
@ Anwar Sekilas, tidak masuk akal. Anda tidak dapat membuat folder dengan nama yang sama dengan file biasa di dalam folder yang sama. Dan findakan melanjutkan dengan folder lain (termasuk subfolder dari folder itu, jika Anda memintanya).
Melebius
9

Anda dapat meneruskan findhasil whilealih-alih forkarena cara ini tidak akan rusak jika nama file memiliki spasi

Pertama cd ke direktori F1, lalu lakukan:

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

Jika direktori ada, mkdirhanya akan menolak untuk membuatnya, jadi tidak ada masalah di sana ...

Jika nama direktori Anda bisa berisi baris baru, atau keanehan eksotis lainnya, gunakan ini yang bisa berurusan dengan nama arbitrer:

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

Terima kasih kepada @terdon untuk bantuannya :)

Zanna
sumber
Jika F1direktori op adalah ~user/Pictures, pindah ke direktori induk dan menjalankan baris akan meletakkan Photodirektori di setiap direktori di ruangnya, yang bisa ribuan. Pertimbangkan untuk menambahkan F1sebagai bagian dari commanline untuk menghindari kesalahan yang mudah dilakukan. Dengan begitu jika secara tidak sengaja dijalankan dari tempat yang salah, itu tidak akan membuat direktori.
LD James
ah ya saya sebenarnya tidak yakin dengan struktur direktori mereka. Saya sarankan untuk melakukannya dari yang sudah F1diedit @LDJames
Zanna
5

Python with os.walkdapat melakukannya dengan cukup mudah dan hanya dalam beberapa baris kode

$ 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

Penjelasan

Apa yang kita hadapi adalah perintah ini: python -c 'import os; [os.mkdir (r + "/ Pictures") untuk r, d, f di os.walk (".")]'

Di sini kita cukup memanggil penerjemah python dengan -cflag untuk menentukan perintah yang kita berikan dalam tanda kutip tunggal. os.walk()fungsi memungkinkan kita untuk melangkah secara rekursif melalui semua subdirektori, dan untuk setiap subdirektori (diwakili oleh r), kita membuat folder Pictures melalui os.mkdir()fungsi. r+"/Pictures"hanyalah manipulasi string sederhana untuk bergabung dengan string subdirektori dan string "/ Gambar" bersama untuk membentuk satu jalur

Ganti "/ Gambar" dengan "/ Foto" agar sesuai dengan kebutuhan Anda

Sergiy Kolodyazhnyy
sumber
4

Jika Anda menggunakan bash, Anda cukup menjalankan:

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

The globstarmerek pilihan **cocok "semua file dan 0 atau lebih direktori dan subdirektori". Dengan kata lain, itu cocok dengan semuanya secara rekursif. Karena /pada akhirnya, **/akan cocok dengan semua direktori dan subdirektori (tidak ada file). Oleh karena itu, $dakan mengulangi semua direktori di direktori saat ini dan subdirektori dan Photosdirektori akan dibuat di masing-masing direktori.

The -pBendera mkdirberarti:

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

Di sini, saya hanya menggunakannya untuk menekan pesan kesalahan jika direktori target sudah ada. Hapus jika Anda ingin melihat kesalahan.

Perhatikan bahwa ini akan gagal membuat Photosubdirektori dalam direktori target yang berisi file bernama Foto. Anda belum menentukan apa yang harus dilakukan dalam kasus-kasus itu dan semua jawaban lain yang diposting sejauh ini juga memiliki batasan ini.

terdon
sumber