bash tablice dwuwymiarowe

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
Awatar użytkownika
CyBEER
Piegowaty Guziec
Piegowaty Guziec
Posty: 15
Rejestracja: 13 wrz 2006, 19:18
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME
Kontakt:

bash tablice dwuwymiarowe

Post autor: CyBEER »

Mam do napisania skrypt, który będzie obliczał wyznacznik macierzy kwadratowej o wymiarze maksymalnym 6x6. Jak zrobić tablicę dwuwymiarową w bashu, ponieważ z tego co wyczytałem w googlach i man bash możliwe są tablice jednowymiarowe? Jak rozwiązać problem wczytania danych do takiej macierzy? i czy jest możliwe wywołanie rekurencyjne skryptu?
Registered Linux user #441023
Awatar użytkownika
mate_haru
Sędziwy Jeż
Sędziwy Jeż
Posty: 47
Rejestracja: 05 paź 2006, 12:42
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: Fluxbox
Architektura: x86_64
Kontakt:

Odp: bash tablice dwuwymiarowe

Post autor: mate_haru »

Macierzy jako takich w czystym bashu nie uzywalem i nie wiem w sumie czy sa :P W kazdym razie juz z rok temu kolega poprosil mnie o napisanie skryptu do sumowania macierzy. Jego kod:

Kod: Zaznacz cały

#!/bin/bash

if test -f "suma.txt"
then
        rm "suma.txt"
fi

if [ -a "dane1.txt" ]
then
        rm "dane1.txt"
fi

if [ -a "dane2.txt" ]
then
        rm "dane2.txt"
fi

wymiar=`cat konfig.txt | awk '{ print $1 }'`  #wymiar macierzy pobrany z pliku

ilosc=$(($wymiar*$wymiar))  #ilosc wszystkich pozycji w macierzy

i=0
liczba1=1
wspX=1
wspY=1
while [ $i -lt $ilosc ]  #petla tworzaca macierze w plikach dane1.txt oraz dane2.txt - macierze sa wypelnione cyframi 1-9
do
        if [ $liczba1 -gt 9 ]
        then
                liczba1=1
        fi

                liczba2=$((10-$liczba1))

        if [ $wspX -eq $wymiar ]
        then
                echo $liczba1 | awk '{ printf "%d\n", $1 }' >> dane1.txt
                echo $liczba2 | awk '{ printf "%d\n", $1 }' >> dane2.txt
                wspX=1
                wspY=$(($wspY+1))
        else
                echo $liczba1 | awk '{ printf "%d ", $1 }' >> dane1.txt
                echo $liczba2 | awk '{ printf "%d ", $1 }' >> dane2.txt
                wspX=$(($wspX+1))
        fi

        if [ $wspY -gt $wymiar ]
        then
                break
        fi

        liczba1=$(($liczba1+1))
done

wspX=1
wspY=1
i=0
while [ $i -lt $ilosc ]   #petla sumujaca macierze zawarte w plikach dane1.txt i dane2.txt
do

        if [ $wspX -gt $wymiar ]
        then
                wspY=$(($wspY+1))
                wspX=1
        fi

        zmienna1=`cat dane1.txt | awk '{ print $"'$wspX'" }'`   #wyciagniecie kolomny okreslonej wspolrzedna X
        zmienna1=`echo $zmienna1 | awk '{ print $"'$wspY'" }'`  #wyciagniecie konkretnej cyfry
        zmienna2=`cat dane2.txt | awk '{ print $"'$wspX'" }'`
        zmienna2=`echo $zmienna2 | awk '{ print $"'$wspY'" }'`
        suma=$((zmienna1+zmienna2))

        if [ $wspX -eq $wymiar ]
        then
                echo $suma | awk '{ printf "%d\n", $1 }'
                wspX=1
                wspY=$(($wspY+1))
        else
                echo $suma | awk '{ printf "%d ", $1 }'
                wspX=$(($wspX+1))
        fi

        i=$(($i+1))
done
Zeby to dzialalo musisz tylko miec plik konfig.txt w katalogu ze skryptem, w ktorym znajduje sie liczba calkowita okreslajaca rozmiar macierzy. Macierze sa tworzone w plikach dane1.txt i dane2.txt. Jak widac pobieranie elementow z nich odbywa sie przy uzyciu AWK. Mam nadzieje, ze ten kod sie przyda.
Pozdrawiam! :)
Awatar użytkownika
CyBEER
Piegowaty Guziec
Piegowaty Guziec
Posty: 15
Rejestracja: 13 wrz 2006, 19:18
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME
Kontakt:

Odp: bash tablice dwuwymiarowe

Post autor: CyBEER »

Dzięki za odpowiedź, ale nie do końca mi oto chodziło. Chciałem się dowiedzieć, czy w bashu można skorzystać z czegoś takiego jak tablica tablic i w jaki sposób się do czegoś takiego odwoływać np. w pętli.
Registered Linux user #441023
Awatar użytkownika
mate_haru
Sędziwy Jeż
Sędziwy Jeż
Posty: 47
Rejestracja: 05 paź 2006, 12:42
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: Fluxbox
Architektura: x86_64
Kontakt:

Odp: bash tablice dwuwymiarowe

Post autor: mate_haru »

Nie znalazlem nic na temat macierzy w bashu. Sadze, ze wygodnie bedzie wiec skorzystac wlasnie z AWK. Nie jest trudny i umozliwi Ci on wykonanie w dosc prosty sposob operacji na macierzach (przegladanie, dodawanie, mnozenie itd. - z pewnoscia wszystko co potrzebne, zebys mogl wykonac zadane przez Ciebie operacje). Jest dosc sporo tutoriali do AWK - nawet po polsku. Nie bedzie problemow, zeby je znalezc. Jak masz w podanym przeze mnie przykladzie - bardzo latwe jest robienie wstawek AWK w kodzie basha. :)
Awatar użytkownika
vytah
Piegowaty Guziec
Piegowaty Guziec
Posty: 24
Rejestracja: 11 paź 2007, 17:44
Płeć: Mężczyzna
Wersja Ubuntu: 7.10
Środowisko graficzne: GNOME
Kontakt:

Odp: bash tablice dwuwymiarowe

Post autor: vytah »

jak już koniecznie chcesz tablice n-wymiarowe, to zrób jednowymiarową i wyskrob funkcję, która z n liczb naturalnych zrobi jedną
f: [0..m-1],[0..n-1]->[0..mn-1]
typu np.
int f(int x,y){ return x+y*m; }
i wtedy zamiast a[x][y] można dać a[f(x,y)]
w bashu programować nie umiem, ale ww. przykład jest chyba dość jasny ;)
kwiatu5
Piegowaty Guziec
Piegowaty Guziec
Posty: 2
Rejestracja: 28 sie 2006, 21:30
Płeć: Mężczyzna
Wersja Ubuntu: 8.10
Środowisko graficzne: GNOME
Kontakt:

Odp: bash tablice dwuwymiarowe

Post autor: kwiatu5 »

Ja jeszcze zaproponuję inną metodę - EVAL.
Jeden wymiar możemy standardowo obsłużyć, ponieważ tablice jednowymiarowe istnieją.
Dwa wymiary natomiast możemy zasymulować dodając sobie do nazwy zmiennej cyferkę a potem używać do jej wywoływania funkcji ewaluującej kod bashowy z ciągu tekstowego.

Kod: Zaznacz cały

day=(Mon Tue Wed Thu Fri Sat Sun)
typ[0]="File does not exist"
typ[1]="No route to host"
typ[2]="Permission denied"
typ[3]="readdir()"
typ[4]="Use of uninitialized value"

for (( j=0; $j <= 6; j++ )) ; do
	for (( i=0; $i <= 4; i++ )) ; do
		temp=`cat error.log | grep "${day[$j]}" | grep "${typ[$i]}" | wc -l`
		eval day_typ_count$j[\$i]=\$\{temp\}
	done
done
Przepraszam za większą ilość kodu, ale warto przeanalizować - szczególnie fragment z eval. Tworzę 7 zmiennych tablicowych day_typ_count1, day_typ_count2, day_typ_count3 itd. Każda ma po 5 elementów w swojej tablicy. Jak je wywołać? Nic prostszego:

Kod: Zaznacz cały

for (( i=0; $i <= 6; i++ )) ;  do
	echo -e "========================\n"
	echo -e "\t${day[$i]}\t\n"
	echo -e "========================\n"
	for (( j=0; $j <= 4; j++ )) ; do
		eval temp=\$\{day_typ_count$i[\$j]\}
		echo "Typ$j: $temp"
	done
	
done
Tutaj wypisuję wszystko na ekran.
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 5 gości