Utwórz rekursywnie folder „Zdjęcie” we wszystkich katalogach


9

Mam kilka folderów i chcę zapętlić wszystkie te foldery iw każdym folderze utwórz inny folder o nazwie „Zdjęcie”

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

Chcę mieć:

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

Odpowiedzi:


8

Z katalogu powyżej F1 uruchom ten skrypt:

Celem skryptu jest uniknięcie tworzenia zbędnych katalogów zdjęć w katalogach zdjęć.

Ponadto jest zaprojektowany tak, aby zapobiec przypadkowemu uruchomieniu go z niewłaściwej lokalizacji, takiej jak katalog główny użytkownika, podczas gdy nie zobaczyłby F1katalogu i błędnie utworzyłby setki katalogów zdjęć w niewłaściwych pałacach.

Ponadto moim zamiarem było stworzenie łatwego do śledzenia skryptu, aby użytkownik mógł go dostosować.

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

Skrypt zaktualizowany:

  • Zmieniono małe litery pw photona wielkie litery.
  • Dodano obsługę niestandardowych nazw plików (z sugestiami Terdon).

1
Zdecydowanie uniknę parsowania ls , może zawieść w nietypowy sposób. Myślę, że odpowiedzi, które tego unikają, są prawdopodobnie bezpieczniejsze.
Arronical

3
@Arronical lsnie jest analizowany. To tylko informacja zwrotna dla użytkownika ... pokazująca, co się dzieje. Podobnie jak słowa „To jest katalog zdjęć”. Informuje użytkownika, dlaczego nie tworzy tam katalogu.
LD James

1
Myślałem, że może tak być, ponieważ nie widziałem, żeby coś z tym zrobiono. W takim razie
wycofuję

find -type d F1, może?
Olivier Grégoire,

Zauważ, że to się nie powiedzie, jeśli zostanie wywołany plik (a nie katalog) $i/Photo, ale OP nie określił, co należy zrobić w takim przypadku. Nie powiedzie się również w przypadku, co jest mało prawdopodobne, gdy jeden z nich $izawiera nowy wiersz.
terdon

24

Możesz to osiągnąć za pomocą jednego findpołączenia.

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

Część -name 'Photo' -prune -omówi, aby nie powracać do istniejących (i nowo utworzonych) Photokatalogów: Jeśli znaleziony plik (lub katalog) ma nazwę Photo, przestań ją przetwarzać ( -prune). W innym przypadku ( -o) przejdź do katalogów ( -type d) i wykonaj ( -exec) polecenie.


ah fajnie, próbowałem w ten sposób i widzę z twojej odpowiedzi, gdzie popełniłem błąd :)
Zanna

@Zanna -prune? :) Tak, to jest dość sprzeczne z intuicją, ale warto się uczyć.
Melebius

Czy przestanie tworzyć folder „Zdjęcie”, jeśli istnieje plik o nazwie „Zdjęcie”?
Anwar

3
@Anwar Obecna wersja będzie. Wymagania są szare. :) Możesz to zmienić, określając -type drazem z -name 'Photo'wcześniej -prune.
Melebius

2
@Anwar Na drugi rzut oka nie będzie to miało sensu. W tym samym folderze nie można utworzyć folderu o takiej samej nazwie jak zwykły plik. I findbędzie kontynuował pracę z innymi folderami (w tym podfolderami tego folderu, jeśli o to poprosisz).
Melebius

9

Możesz przekazać findwyniki whilezamiast, forponieważ w ten sposób nie zepsuje się, jeśli nazwy plików mają spacje

Najpierw cd do katalogu F1, a następnie wykonaj:

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

Jeśli katalog istnieje, mkdirpo prostu odmówi jego utworzenia, więc nie ma problemu ...

Jeśli nazwy katalogów mogą zawierać znaki nowej linii lub inną egzotyczną dziwność, użyj tego, który może poradzić sobie z dowolnymi nazwami:

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

Dzięki @terdon za pomoc w tym :)


Jeśli F1katalog op jest ~user/Pictures, przejście do katalogu nadrzędnego i uruchomienie wiersza spowoduje umieszczenie Photokatalogu w każdym katalogu w jego przestrzeni, który może wynosić tysiące. Zastanów się nad dodaniem F1jako części linii poleceń, aby uniknąć łatwo popełnionego błędu. W ten sposób, jeśli zostanie przypadkowo uruchomiony z niewłaściwego miejsca, nie utworzy katalogów.
LD James

ah tak, tak naprawdę nie byłem pewien ich struktury katalogów. Sugeruję zrobienie tego F1zamiast tego, pod redakcją @LDJames
Zanna

5

Python z os.walkmoże to zrobić dość łatwo i tylko w kilku wierszach kodu

$ 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

Wyjaśnienie

Mamy do czynienia z następującą komendą: python -c 'import os; [os.mkdir (r + „/ Pictures”) dla r, d, f w os.walk („.”)]'

Tutaj po prostu wywołujemy interpreter Pythona z -cflagą, aby określić polecenie, które wydajemy w ramach pojedynczych cudzysłowów. os.walk()Funkcja pozwala nam rekurencyjnie przechodzić przez wszystkie podkatalogi, a dla każdego podkatalogu (reprezentowanego przez r) tworzymy folder Obrazy za pomocą os.mkdir()funkcji. r+"/Pictures"jest tylko prostą manipulacją ciągiem, aby połączyć ciąg podkatalogu i ciąg „/ Pictures”, tworząc jedną ścieżkę

Zamień „/ Pictures” na „/ Photo”, aby spełnić Twoje wymagania


4

Jeśli używasz bash, możesz po prostu uruchomić:

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

Te globstarmarki opcja **pasuje „wszystkie pliki i 0 lub więcej katalogów i podkatalogów”. Innymi słowy, dopasowuje wszystko rekurencyjnie. Ze względu /na koniec **/pasuje do wszystkich katalogów i podkatalogów (bez plików). Dlatego $dbędą iterować wszystkie katalogi w bieżącym katalogu i ich podkatalogach, a Photoskatalog zostanie utworzony w każdym z nich.

-pFlaga mkdirśrodków:

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

Tutaj używam go po prostu do ukrywania komunikatów o błędach, jeśli katalog docelowy już istnieje. Usuń go, jeśli chcesz zobaczyć błędy.

Pamiętaj, że nie uda się utworzyć Photopodkatalogu w katalogu docelowym, który zawiera plik o nazwie Zdjęcie. Nie określiłeś jednak, co należy zrobić w tych przypadkach, a wszystkie inne dotychczas opublikowane odpowiedzi również mają to ograniczenie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.