Nowe posty

Autor Wątek: rekurencyjne przeszukiwanie katalogów  (Przeczytany 6792 razy)

peiner

  • Gość
rekurencyjne przeszukiwanie katalogów
« dnia: 2009-10-26, 23:45:51 »
Mam za zadanie napisać skrypt rekurencyjnie przeszukujący katalogi w poszukiwaniu pliku. Jako pierwszy argument skryptu podaje się nazwę pliku, jako drugi katalogu. Program nie ma być oparty na poleceniu find. Jeśli w podanym katalogu znajdzie inne katalogi musi się sam wywołać w tych katalogach - rekurencyjnie,jako osobny proces. Ma ktoś pomysł ? Ja naklepałem coś takiego:

for i in $2 
do
  #jeżeli plik jest katalogiem ( -d )
  if [ -d $i ]
  then
  find.sh $1 $i
  fi
  #jeżeli plik jest plikiem ( -f )
  if [ -f $i ]
  then
  if [ $1 $i ]
then
echo 'Znalazłem plik $1 w $2'
fi
  fi
 
done
Ale to nie działa.

arctgx

  • Gość
rekurencyjne przeszukiwanie katalogów
« Odpowiedź #1 dnia: 2009-10-27, 13:11:10 »
Skomentowałem wewnątrz:
#!/bin/bash
for i in "$2"/*                                   #1 - $2, jak wiesz, to tylko jeden podany argument
do
#echo "element $i:"
  #jeżeli plik jest katalogiem ( -d )
  if [ -d "$i" ]
  then
      $0 "$1" "$i"                                  #2 - $0 to nazwa bieżącego polecenia
  fi
  #jeżeli plik jest plikiem ( -f )
  if [ -f "$i" ]
  then
#       echo "porównuję $1 z $i"
     if [ "$1" = "$(basename $i)" ]             #3  - odkomentuj linię wyżej i zobaczysz, co się dzieje, przy okazji: nie dałeś znaku równości
    then
    echo "Znalazłem plik \\"$1\\" w $2"           #4  - wewnątrz apostrofów dolar jest cytowany dosłownie, wewnątrz cudzysłowów - już interpretowany przez powłokę
    fi
  fi
done
Zamiast osobnego odpalanego procesu powłoki lepiej ująć ten kod w funkcję.

[edycja] Jeden wspólny komentarz: bez ujmowania nazw zmiennych w cudzysłów program wysypie się na nazwach zmiennych zawierających spacje. Cudzysłów chroni spacje przed interpretacją. Dla przykładu w wyszukiwanym katalogu wykonaj mkdir a\\ b.

Zamiast zewnętrznego polecenia  "$(basename $i)", można wykorzystać powłokową postać "${i##*/}" znaną nie tylko z basha.

Zapoznaj się z manualem basha - zaczynając od tego, co jest Ci potrzebne, np. rozwijania nazw plików.

peiner

  • Gość
rekurencyjne przeszukiwanie katalogów
« Odpowiedź #2 dnia: 2009-10-27, 14:03:44 »
A co zrobić żeby w przypadku ani jednego wystąpienia podanej nazwy wyświetlić komunikat "Nic nie znalazłem"  ale tylko raz ?

arctgx

  • Gość
rekurencyjne przeszukiwanie katalogów
« Odpowiedź #3 dnia: 2009-10-27, 15:29:08 »
Większość odpowiedzi nie kryje się w znajomości powłoki, ale już w mniej lub bardziej wyszukanej pomysłowości. Od ręki, możesz np. w momencie znalezienia wprowadzić zmienną i przypisać jej cokolwiek niepustego. Po przeszukaniu, jeśli zachowała się pusta lub nieustawiona, wypisujesz komunikat. Zamiast instrukcji if, możesz uzyć czego w stylu echo ${PLIK_WYNIKOWY:-Nic} (jak to działa: man bash).

Możesz też próbować bawić się kodem wyjścia (exit), ale w tym celu chyba praktyczniej byłoby podzielić kod na funkcje.

peiner

  • Gość
rekurencyjne przeszukiwanie katalogów
« Odpowiedź #4 dnia: 2009-10-27, 16:41:49 »
Czy istnieje możliwość zmiany argumentów wejściowych przez sam skrypt na twardo tzn.np.przypisanie do zmiennej $1 na stałe dowolnej stałej ?

arctgx

  • Gość
rekurencyjne przeszukiwanie katalogów
« Odpowiedź #5 dnia: 2009-10-27, 17:23:07 »
Nie wiem jaki to ma sens, ale patrz ang. lub polski man bash do rozdziału na temat parametrów pozycyjnych (Positional Parameters).