Jak utworzyć katalog we wszystkich podkatalogach?

34

Załóżmy, że mam taką strukturę katalogów:

$ [~ / ćwiczenie] ls
a / b / c / d /

Teraz chcę utworzyć katalog tmp1we wszystkich podkatalogach practicei robię to:

$ [~ / praktyka] mkdir * / tmp1
mkdir: nie można utworzyć katalogu `* / tmp1 ': Brak takiego pliku lub katalogu

Następnie próbuję -pprzełączyć i kończę na katalogu o nazwie *z podkatalogiemtmp1

$ [~ / praktyka] mkdir -p * / tmp1

$ [~ / ćwiczenie] ls
* / a / b / c / d /

Wiem, że użycie -pprzełącznika polega na tworzeniu wielu nieistniejących katalogów. Pomyślałem, że to może pomóc.

Jak utworzyć tmp1we wszystkich podkatalogach jednocześnie?

Jeśli można to zrobić, w jaki sposób przedłużyć go do tworzenia \tmp1, \tmp2, \tmp3w \a, \bi \cnaraz?

Edit: Brakowało mi wspomnieć, że katalogi nie muszą być proste i celem, jak a, b, citd., A katalog ma zostać utworzony niekoniecznie jest jak tmp1, tmp2.

$ [~ / ćwiczenie] ls
pies / kot / szczur /

W nich chciałbym mieć coś takiego

$ [~ / ćwiczenie] ls *
pies:
czerwony niebieski/

kot:
czerwony niebieski/

szczur:
czerwony niebieski/
Animesh
źródło
1
Biorąc pod uwagę odpowiedź Christophera , powinieneś wyjaśnić, czy „create \ tmp1, \ tmp2, \ tmp3 w \ a, \ b i \ c” powinno dać w sumie 3 lub 9 podkatalogów.
manatwork
@manatwork: To dobry punkt. Powinien utworzyć 9 podkatalogów.
Animesh
Ta moja pomoc w rozwiązaniu problemu z przestrzenią w nazwie katalogu sudo find ./ -depth -type d -exec echo '"{} / RCS"' \;

Odpowiedzi:

44

Z globami :

for dir in */; do mkdir -- "$dir/tmp1"; done

UWAGA

  • Traktuję tylko katalogi (w tym dowiązania symboliczne do katalogów) z niewielkim wysiłkiem używania */globu
  • Jeśli chcesz utworzyć wiele podkatalogów jednocześnie:

    for dir in */; do mkdir -- "$dir"/{tmp1,foo,bar,qux}; done

Gilles Quenot
źródło
Czy mogę zrobić for i in */; do mkdir "$i/itemone" "$i/itemtwo"; donewiele nazw katalogów, które nie są uporządkowane?
Animesh
Przetestowałem to i jest to bardzo możliwe. Dzięki.
Animesh
Zobacz mój zredagowany post
Gilles Quenot,
1
Rozwinięcie nawiasu klamrowego nie jest wykonywane w ciągu cytowanym.
manatwork
Tak, dziękuję, post edytowany przez Stephane Chazelas odpowiednio ...
Gilles Quenot
10

[...] jak mogę go rozszerzyć, aby jednocześnie utworzyć \ tmp1, \ tmp2, \ tmp3 w \ a, \ b i \ c?

 mkdir {a,b,c}/tmp{1,2,3}
Krzysztof
źródło
10

Z GNU lub BSD * znajdź:

find -mindepth 1 -maxdepth 1 -type d -exec mkdir {}/newdir \;

lub używając rozszerzenia parametrów:

dirs=(*/)
mkdir -- "${dirs[@]/%/newdir}"

* Obejmuje OS X

kojiro
źródło
2
Ze standardową składnią find:find . -name . -o -prune -type d -exec sh -c 'exec mkdir "$1/newdir"' sh {} \;
Stéphane Chazelas,
1
Zwróć także uwagę na różnice między tymi dwoma rozwiązaniami: pierwsze zawiera ukryte katalogi, drugie doda nowy katalog do katalogów połączonych dowolnym dowiązaniem symbolicznym w bieżącym katalogu.
Stéphane Chazelas,
6

Nie na temat, ponieważ wspominasz bash, ale dla przypomnienia , z zsh zrobiłbyś:

dirs=(*(/))
mkdir -- $^dirs/tmp1

$^varwłącza nawiasy klamrowe dla rozszerzenia tablicy. To przypomina rc„s ^operatora i rc(lub jego pochodna es), można napisać:

dirs=(*/)
mkdir -- $dirs^tmp1

Należy jednak pamiętać (i to samo dotyczy podanych tutaj rozwiązań bash), że w rozwiązaniu rc dirszawierałyby również dowiązania symboliczne do katalogów. W rozwiązaniu zsh zmień *(/)na, *(-/)jeśli chcesz dołączyć dowiązania symboliczne do katalogów.

Stéphane Chazelas
źródło
+1 za punkt dotyczący dowiązań symbolicznych! Takie zachowanie może być pożądane, ale skargę mkdir dotyczącą utworzenia zduplikowanego katalogu można ukryć za pomocą -pflagi.
kojiro
4

Przenośnie, zapętlaj katalogi nadrzędne:

for d in */; do mkdir "$d/red" "$d/blue"; done

Dodaj --po, mkdirjeśli możesz mieć katalogi, których nazwa zaczyna się od -.

W Zsh możesz to zrobić jednym poleceniem za pomocą e kwalifikatora glob :

mkdir *(/e\''REPLY=($REPLY/{red,blue})'\')

ale szybciej jest wpisać to jako dwa polecenia:

d=(*(/)); mkdir $^d/{red,blue}
Gilles „SO- przestań być zły”
źródło
1
Na stronie, która ma być odniesieniem, wolałbym powiedzieć „ mkdir -- whateveri pomiń, -- jeśli zamierzasz rozszerzyć wszystko, co może być wzięte za opcje mkdirpolecenia”. Nie ma sensu --tutaj pomijać . W przypadku PO może nie być to problemem, ale w ogólnym przypadku jest to jeden problem. Myślę, że mamy obowiązek uczyć tutaj poprawnej i bezpiecznej składni.
Stéphane Chazelas
@StephaneChazelas W kontekście skryptów zawsze umieszczam wszystkie niezbędne --i cytaty oraz duże ostrzeżenia, gdy znaki nowej linii nie są obsługiwane. W kontekście wiersza poleceń wolę pokazywać szybką wersję, która najpierw działa w praktyce, a wersję kuloodporną jako uzupełnienie.
Gilles „SO- przestań być zły”
1

Możesz to zrobić w ten sposób:

mkdir {a,b,c,d}/tmp1
ДМИТРИЙ МАЛИКОВ
źródło
1
Co jeśli ma 100 katalogów?
Bernhard,
1

Odmiana odpowiedzi sputnick, która pozwala uniknąć plików spoza katalogu:

for x in *; do if [ -d "$x" ]; then mkdir "$x/tmp1"; fi; done
Złotowłosa
źródło
Traktuję tylko reż, to cała magia ...
Gilles Quenot,
fajnie,
rozumiem
2
Czy nie powinno tak być if [ -d "$x" ];…?
kojiro
Tak. Praktycznie nigdy nie mam spacji w nazwach plików i zwykle zapominam o takich rzeczach ...
goldilocks
1

Jest to dobry ze starych Unix Masters (testowany na FreeBSD 10.1), jeśli chcesz kontrolować wersję (z zablokowanym RCS: ci -l z krótkim komentarzem jako ir: do pierwszej wersji) plików konfiguracyjnych / etc / * na ~ / .his / etc

sudo rsync -av /etc/ ~/.his
sudo find -d ~/.his/etc -type d -exec echo '{}/RCS' \; | xargs sudo mkdir -p
sudo find -d ~/.his/etc \! -name "RCS" | xargs sudo ci -l -mir -t-ir
użytkownik108341
źródło
Nie rozumiem, jak ta odpowiedź OP
Archemar
1

Powinno być \! nazwa „RCS” i działa najlepiej przy pierwszym zameldowaniu.

sudo znajdź ~ / .his / etc \! -nazwa „RCS” -ls

sudo znajdź -d ~ / .his / etc \! -nazwa „RCS” | xargs sudo ci -l -mir -t-ir

Ten ostatni działa również bardzo dobrze w przypadku częściowego filtrowania całej zawartości RCS w nazwie pliku:

sudo znajdź -d ~ / .his / etc -type f | grep -v RCS | xargs sudo ci -l -mir -t-ir

użytkownik108341
źródło
1

to dla mnie wielka pomoc. musiałem utworzyć zestaw podkatalogów w wielu folderach i coś takiego:

!/bin/sh

cd /dest/cont

for dir in */*/; do
    mkdir -p -- $dir/{FB,Video,Audio,proj};
done

działał świetnie, z wyjątkiem przypadku napotkania białej przestrzeni. czy istnieje sposób na zignorowanie spacji w */*/części argumentów?

johno
źródło