Zautomatyzowany sposób tworzenia drzewa katalogów

11

Próbuję utworzyć drzewo katalogów od A do Z, w którym następny katalog znajduje się w bieżącym katalogu.

Na przykład: B znajduje się w przedziale A, a C w przedziale B itd.

-A
--B
---C
----...Z

Wszelkie wskazówki, jak to zrobić w sposób zautomatyzowany?

Nish
źródło
Zastanawiam się, jaki jest praktyczny cel takich katalogów. IMHO wygląda to bardziej na pytanie do Code Golfa .
Melebius
3
@Mebebius Jednym z możliwych celów jest utworzenie struktury katalogów jako przypadku testowego, aby pomóc w sprawdzeniu, czy działa inna właściwość polecenia, skryptu lub aplikacji. Oto niedawny przypadek, w którym samo pytanie nie dotyczyło tworzenia określonych struktur katalogów, ale wiedza na temat pisania poleceń w tym celu była przydatna do celów testowych, nie pomimo tego, jak konkretna struktura była wymyślona i dziwna, ale z tego powodu. (Mamy też wiele pytań na temat tworzenia określonych struktur katalogów, które można znaleźć, wyszukując „ mkdir -p”.)
Eliah Kagan 10.04.18

Odpowiedzi:

25

Z mkdir, printfi ekspansja klamra Bash za:

$ mkdir -p "$(printf "%s/" {A..Z})"
$ tree A
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

25 directories, 0 files
  • {A..Z}rozszerza się A B ... Z,
  • printf "%s/"wypisuje argumenty /po nich, więc rozumiemA/B/...Z/
  • i mkdir -ptworzy A/B/.../Zkatalog z dowolnymi katalogami nadrzędnymi, które wymagały utworzenia.
muru
źródło
Dziękuję za to. Myślałem, że dostaję ten błąd podczas. Używam polecenia mkdir: 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: Brak takiego pliku lub katalogu
Nish
3
@Nish Jest -pw mkdirpoleceniu.
muru
mój zły, próbowałem tego na moim komputerze Mac zamiast Ubuntu. Kolejne pytanie brzmi: - powiedzmy, że chciałem mieć katalog A1..A100 w obrębie A (w tej samej strukturze AtoZ). Następnie B1..B100 w obrębie B. Więc wygląda to mniej więcej tak -> imgur.com/jfuKEdf
Nish
11
Załóżmy, że zamieszczasz kontynuację jako rzeczywiste pytanie zamiast w komentarzach i nie używałeś obrazów, tylko tekstu. To byłoby o wiele lepsze, nie?
muru
Rozumiem twój punkt tutaj. Trudno go opublikować, ponieważ nie jest to kod i jest to ogromny wynik. Więc samo spojrzenie na zrzut ekranu ułatwia zrozumienie.
Nish,
7

Na bardzo prostym poziomie można użyć {A..Z}rozszerzenia do wygenerowania całej litery, a następnie iteracyjnie utworzyć i wprowadzić każdą z nich:

~/test_directory$ for d in {A..Z}; do mkdir "$d"; cd "$d"; done
~/test_directory/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$ 

Jak widać w moim wierszu polecenia, masz już całkowicie łańcuchowy katalog.

Jeśli jednak rzeczywiste nazwy katalogów są inne niż tylko alfabet, musisz w jakiś sposób podać listę nazw katalogów, być może za pośrednictwem pliku, nad którym iterujesz i ponownie wykonujesz ten sam proces. Zasadniczo to

while IFS= read -r dir_name;do mkdir "$dir_name"; cd "$dir_name" ;done < directory_list.txt
Sergiy Kolodyazhnyy
źródło
to fajnie. Oto kolejne pytanie. powiedzmy, że chciałem mieć katalog A1..A100 w obrębie A (w tej samej strukturze AtoZ). Następnie B1..B100 w obrębie B. Więc wygląda to mniej więcej
Nish
@Nish ah, to wymagałoby wewnętrznej pętli, więcfor d in {A..Z}; do mkdir "$d"; cd "$d"; for i in {1..100}; do mkdir "${d}${i}" ;done ; done
Sergiy Kolodyazhnyy
Lub nawet bez wewnętrznej pętli,for d in {A..Z}; do mkdir "$d"; cd "$d"; mkdir "$d"{1..100}; done
Sergiy Kolodyazhnyy
Dziękuję za to. Wygląda na to, że działa, ale kolejność katalogu wydaje się zepsuta, więc 2 nie jest po 1. Jest losowo sortowane. W każdym razie to naprawić? Oto zrzut ekranu -> imgur.com/a/Zqj1c
Nish
@Nish Porządek sortowania jest oparty na tekście, a nie liczbowy, jak sądzę. Na razie treenie jestem pewien, jak to naprawić, ale myślę, że może to nawet nie stanowić treeproblemu, ale raczej porządek sortowania powłoki. Proponuję zadać aktualne pytanie na ten temat albo tutaj, albo jeszcze lepiej na unix.stackexchange.com
Sergiy Kolodyazhnyy
2

Mimo, że sposób Muruprintf nie może zostać pokonany, osobiście lubię jottakie rzeczy. jotnie jest domyślnie instalowany w Ubuntu. athena-jotPakiet zawiera go. Każde z tych poleceń działa:

mkdir -p "$(jot -s/ -c 26 A)"
jot -s/ -c 26 A | xargs mkdir -p

Ułatwi to naprawdę każde polecenie, które generuje sekwencję liter i łączy je ukośnikami, ponieważ ich dane wyjściowe można następnie przekazać mkdir -palbo przez zastąpienie polecenia (jak w odpowiedzi muru ), albo za pomocą xargs. Oto kilka przykładów z użyciem kilku narzędzi xargs, które nie wymagają instalacji oprogramowania, z wyjątkiem być może na bardzo minimalnych systemach lub Ubuntu Core:

perl -we 'print join "/", A..Z' | xargs mkdir -p
ruby -we 'print (?A..?Z).to_a * ?/' | xargs mkdir -p
python3 -c 'print("/".join(__import__("string").ascii_uppercase))' | xargs mkdir -p

Stare wersje Ubuntu pochodzi z Python 2 zamiast Python 3. W tym celu wystarczy zmienić python3się python, aby to ostatnie dzieło polecenia, jeśli naprawdę chcesz to zrobić z poziomu Pythona.

Podobnie, krótki i prosty sposób muru można alternatywnie napisać:

printf '%s/' {A..Z} | xargs mkdir -p

Końcowe /, w ścieżce katalogu, o którą mkdir -pprosi się o utworzenie, nie stanowi problemu i jest prawdopodobnie preferowane stylistycznie. Ale można to pominąć, podobnie jak inne przykłady w tej odpowiedzi.

Eliah Kagan
źródło