Nowe posty

xx FirebirdSQL server w xinetd (1)
Wczoraj o 08:31:48
xx [SOLVED] Poczta Linux.pl (9)
2022-08-09, 15:09:29
xx Dostęp z komputerów z windowsem do plików udostępnionych na serwerze linux (samb (0)
2022-08-08, 20:27:55
xx brak uprawnienia do zamontowanej partycji ntfs - elementaryOS 6,1 (5)
2022-08-08, 06:36:07
xx Jak zainstalować sterowniki do karty sieciowej TP LINK WN350GD (1)
2022-08-04, 05:55:46
xx Ubuntu vs Fedora (1)
2022-07-26, 03:40:58
xx virtualization technology (1)
2022-07-25, 21:27:10
xx Migracja z centos 6 na centos 7 (3)
2022-07-25, 07:31:19
xx akonadi w KDE5 (10)
2022-07-22, 23:34:05
xx Alternatywa dla Delphi (7)
2022-07-22, 15:27:42

Autor Wątek: Funkcja rekurencyjna tworząca drzewo katalogów  (Przeczytany 5562 razy)

cadi2108

  • Gość
Funkcja rekurencyjna tworząca drzewo katalogów
« dnia: 2010-02-06, 20:22:09 »
Witam ponownie!

Już dwa dni próbuję napisać funkcję, którą gdy się wywoła w następujący sposób:

create_directory $directory 2 2
to otrzymamy drzewo katalogów w katalogu $directory o głębokości 2 i z 2 katalogami w każdym katalogu, czyli:

            $directory
                 |
         ================
         |               |
     ========        =========
     |      |        |       |
     |      |        |       |
natomiast gdy wywołam

create_directory $directory 3 2
to otrzymamy drzewo katalogów w katalogu $directory o głębokości 3 i z 2 katalogami w każdym katalogu, czyli:

            $directory
                 |
         ================
         |               |
     ========        =========
     |      |        |       |
   =====  =====     ====    ====
   |   |  |   |     |  |    |  |
   |   |  |   |     |  |    |  |
Poniżej znajduje się kod źródłowy mojej funkcji... niestety z rekurencji nigdy nie byłam mocna ;/

 
function create_directory() {
  if [ $depth -eq 0 ]; then
    return 1
  fi
 
  for i in `seq 1 $3`; do
    mkdir $1/$i
  done
  (( tmp=$2-1))
  create_directory $1/$i $tmp $3
}
Czy ktoś może widzi co w tej funkcji mam nie tak, że nie chodzi tak jak trzeba? Będę bardzo wdzięczna za wszelkie uwagi.

arctgx

  • Gość
Funkcja rekurencyjna tworząca drzewo katalogów
« Odpowiedź #1 dnia: 2010-02-06, 23:01:03 »
#!/bin/bash
create_directory() {
local depth=$2
local i
if [[ $depth -gt 0 ]]
then
echo depth=$depth kat=$1 liczba=$3
for ((i=1;i<=$3;i++))
do
mkdir -p $1/$i
echo $1/$i i=$i
create_directory "$1/$i" $((depth-1)) $3
done
echo depth_na_koncu=$depth
fi
echo koniec
}
rm -rf x
create_directory x 3 3
find x
Zerknij na wstępną wersję z linijkami debugującymi. Nie wiem czym różni się u Ciebie zmienna depth od tmp. Pierwsze co mi do głowy przyszło to zadeklarować depth jako zmienną lokalną w funkcji (żeby jej wewnętrzne wywołania nie nadpisywały). To jednak nie dało jeszcze tego co trzeba (zmienna i ruszała tylko raz). Spędziłem jakąś godzinkę czasu co jest nie tak. Do teraz nie rozpracowałem solidnie, dlaczego gdy zmienną sterującą w pętli zadeklarowałem jako lokalną, funkcja zaczęła dawać to co trzeba (przynajmniej na kilku przykładach). To więc tylko przypadek, w dodatku niepewny.

P.S. Może znajdę chwilę by przekonać się co zrobiłem ;)

arctgx

  • Gość
Funkcja rekurencyjna tworząca drzewo katalogów
« Odpowiedź #2 dnia: 2010-02-06, 23:38:48 »
Chyba zaczynam łapać, dlaczego zmienna i  nie ruszała w zewnętrznej pętli więcej niż raz. Wewnętrzna pętla (ta najgłębsza) ustawiała ją na $3, a że zmienna nie miała lokalnego charakteru, to i po wyjściu z pierwszej najgłębszej pętli była większa niż $3. Dlatego próba drugiej iteracji mówiła że już nie ma nic do roboty.

Można powiedzieć inaczej: różne istniejące naraz pętle używały tej samej zmiennej, co dawało zamieszanie. Stworzenie lokalnej kopii dało to, że wartość nie wpływa na wartości zmiennej o tej samej nazwie w innych wywołaniach, także w tych wyżej. To już wydaje mi się w miarę solidnym wyjaśnieniem.

create_directory() {
local depth=$2
local i
if [[ $depth -gt 0 ]]
then
for ((i=1;i<=$3;i++))
do
mkdir -p $1/$i
create_directory "$1/$i" $((depth-1)) $3
done
fi
}

cadi2108

  • Gość
Funkcja rekurencyjna tworząca drzewo katalogów
« Odpowiedź #3 dnia: 2010-02-07, 10:24:50 »
Działa wspaniale! Dziękuję bardzo za pomoc :)