[Rozw] wczytywanie wieloliniowego tekstu do tablicy

Problemy dotyczące programowania.

Moderatorzy: Moderatorzy, Administratorzy

Awatar użytkownika
kyan
Użytkownik
Posty: 114
Rejestracja: 2008-04-22, 05:35
Lokalizacja: /home/kyan/

[Rozw] wczytywanie wieloliniowego tekstu do tablicy

Post autor: kyan »

Witam

Staram się poradzić sobię z danymi wysyłanymi przez pewien program. Program generuje wielowierszowe dane (każda linijka to 1 'rekord'). Zastanawiam się jak można ładnie wczytać to do tablicy. Problemem jest to że poszczególne linijki mogą zawierać białe znaki - w innym wypadku coś takiego spisuje się całkiem nieźle:

Kod: Zaznacz cały

 TEST=($(program | xargs)) 
Ładnie zapisuje mi oddzielnie każdą linijkę w osobnym elemencie tableli.

Narazie wykombinowałem coś takiego aby przekazać dane zawierające spacje (zakładam, że '|' nie znajdzie się w danych wynikowych programu):

Kod: Zaznacz cały

TEST=(\"$(program | sed 's/^/|/' | xargs | cut -c2- | sed 's/ |/" "/g')\")
Wszystko super poza tym, że poszczególne elementy tabeli wyglądają tak:

Kod: Zaznacz cały

$ echo ${TEST[0]}
"element1"
$ echo ${TEST[1]}
"element 2"
itd...
Co ciekawe przypisanie

Kod: Zaznacz cały

TEST=("element1" "element 2" ... )
pomija w wyniku apostrofy:

Kod: Zaznacz cały

$ echo ${TEST[0]}
element1
$ echo ${TEST[1]}
element 2
itd...
Ma ktoś pomysł w jaki sposób można to efektywniej zrobić? (Tak wiem mogę poprostu powycinać te apostrofy ale zastanawiam się czy czegoś nie robię źle i nie ma szybszych i prostrzych rozwiązań)

PS. Tylko bash z sedem, awkiem, cutem, itp. php, perl... odpadają
Ostatnio zmieniony 2009-11-22, 02:07 przez kyan, łącznie zmieniany 1 raz.

Awatar użytkownika
Hannibal
Moderator w st. spocz.
Posty: 1644
Rejestracja: 2004-06-08, 16:03
Lokalizacja: Łódź
Kontakt:

Re: [Rozw] wczytywanie wieloliniowego tekstu do tablicy

Post autor: Hannibal »

Podaj jakieś przykładowe dane i co chcesz osiągnąć ogólnie - być może nie potrzebujesz tablicy ;).
[size=75]Hannibal@current@2.6.X[/size]

Awatar użytkownika
kyan
Użytkownik
Posty: 114
Rejestracja: 2008-04-22, 05:35
Lokalizacja: /home/kyan/

Re: [Rozw] wczytywanie wieloliniowego tekstu do tablicy

Post autor: kyan »

ok skrypt odpytuje użądzenie sieciowe wykorzystując snmpwalk

odpytywane są takie wartości jak operacyjny i administracyjny status, typ i opis interfejsu (opis zawiera zwykle wspomniane białe znaki) każdy z typów wartości odpytany jest oddzielnie

wyniki zapisywane są w tablicach 1 element tablicy - wartość dla 1 interfejsu

przykład:

wynik snmpwalk dla odp tablicy indeksów interfejsów (dla każdego interfejsu w oddzielnej linii):

Kod: Zaznacz cały

1
2
3
...
...dla opisów

Kod: Zaznacz cały

opis 1 interfejsu
opis 2 interfejsu
opis 3 interfejsu
...
po czym w pętli dla każdego elementu tablicy z indeksami interfejsów wypisywane są wartości (+ formatowanie kolorami)
przykład

Kod: Zaznacz cały

typ_interfejsu_1 status_interfejsu_1 opis interfejsu 1
typ_interfejsu_2 status_interfejsu_2 opis interfejsu 2
typ_interfejsu_3 status_interfejsu_3 opis interfejsu 3
staram się jak najbardziej ograniczyć ilość zapytań SNMP do urządzenia a snmpwalk pozwala pobrać łatwo wszystkie wartości danego typu (np typ) dla wszystkich interfejsów w 1 zapytaniu

jak napisałem użycie czegoś ponad bash i standardowo dostępne programy typu sed, awk, cut czy (e)grep odpada niestety

Awatar użytkownika
Hannibal
Moderator w st. spocz.
Posty: 1644
Rejestracja: 2004-06-08, 16:03
Lokalizacja: Łódź
Kontakt:

Re: [Rozw] wczytywanie wieloliniowego tekstu do tablicy

Post autor: Hannibal »

Program jest mi nie znany ale jego testowe uruchomienie okresliło następujący format danych:

Kod: Zaznacz cały

Jakieś coś :: nazwa właściwości . numer = typ wartości : wartość
IMHO można wszytko w awk zrobić:
Dla każdej lini
1. Sprawdzasz regexpem interesującą cię nazwę właściwości
2. Wciągasz regexpem jej numer
3. Wyciągasz regexpem jej wartość
4. Wrzucasz do tabeli danej właściwości pod wciągniętym numerem wartość

Na koniec wypisujesz dla każdego numeru wartości z kolejnych tablic
[size=75]Hannibal@current@2.6.X[/size]

Awatar użytkownika
kyan
Użytkownik
Posty: 114
Rejestracja: 2008-04-22, 05:35
Lokalizacja: /home/kyan/

Re: [Rozw] wczytywanie wieloliniowego tekstu do tablicy

Post autor: kyan »

jedyny problem jaki mam jest wspomniany w tytule ;) zamiana tego:

Kod: Zaznacz cały

jakis sobie opis
jakis sobie opis 2
jakis sobie opis 3
...
na tablice w wygodny sposob

co do snmpwalka to odpytuje urzadzenia sieciowe wykorzystujac SNMP

np snmpwalk -v1 -Oevq -c public 192.168.1.1 ifDescr (z odpowiednim IP i community string)

moze (tu dla switcha Cisco) zwrocic:

Kod: Zaznacz cały

Vlan1
GigabitEthernet0/1
GigabitEthernet0/2
GigabitEthernet0/3
...
GigabitEthernet0/24
Null0
jako ze zawsze (przy odp. skonstruowanych zapytaniach) dostane taka sama ilosc danych najlatwiej przechowywac to w tablicach: tablica_typu, tablica_statusu, tablica_opisu itp...

jedyny problem z przeksztalceniem wielolinijkowych danych wejsciowych w tablice gdy zawieraja one spacje (przepuszczenie przez samo xargs wygeneruje mi potem tablice o innej dlugosci)

ok jeszcze 1 przyklad

program wyswietl_typ da wynik:

Kod: Zaznacz cały

typ1
typ2
typ3
...
typ20
z czego mam tablice 20 elementowa przepuszczajac przez xargs

program wyswietl_opis da wynik:

Kod: Zaznacz cały

typ1
opis 1
opis 2
...
opis 20
z czego dostane tablice 40 elementowa przepuszczajac tylko przez xargs:
elem 1 - opis
elem 2 - 1
elem 3 - opis
elem 4 - 2
...

a chcialbym miec tak:
elem 1 - opis 1
elem 2 - opis 2
elem 3 - opis 3
elem 4 - opis 4
...

jako, ze odpytanie przez od razu o liste elementow zamiast odpytywanie pojedynczo o kazdy jest szybsze co sprawdzilem empirycznie ;) wciaz szukam rozwiazania

Awatar użytkownika
olek
Moderator
Posty: 63
Rejestracja: 2004-05-22, 00:37
Lokalizacja: Warszawa
Kontakt:

Re: [Rozw] wczytywanie wieloliniowego tekstu do tablicy

Post autor: olek »

z tego co zrozumiałem problemem są spacje w wartościach zmiennych, żeby dodać zmienną która zawiera spacje

Kod: Zaznacz cały

TABLICA[1]='abc abc abc'
lub załadować zmienne z pliku (plik tab)

Kod: Zaznacz cały

root@host:~/test_tablica# cat ./tab
element 1 1
element 2 2
element 3 3
element 4 4
element 5 5
dodaj do tablicy (ewentualnie przed usuniecie zmiennych "unset TABLICA O IFS")

Kod: Zaznacz cały

set -f; O=$IFS IFS=$'\n' TABLICA=($(< ./tab)) IFS=$O; set +f
listowane elementów tablicy

Kod: Zaznacz cały

root@host:~/test_tablica# for e in "${TABLICA[@]}"; do echo $e; done
element 1 1
element 2 2
element 3 3
element 4 4
element 5 5
Ostatnio zmieniony 2009-11-19, 01:05 przez olek, łącznie zmieniany 1 raz.
Olek
slackware 7.1, 8.1, 9.1, 10.1, 11.1, 12.2 | www.olek.waw.pl | sklep.12a.pl

Awatar użytkownika
kyan
Użytkownik
Posty: 114
Rejestracja: 2008-04-22, 05:35
Lokalizacja: /home/kyan/

Re: [Rozw] wczytywanie wieloliniowego tekstu do tablicy

Post autor: kyan »

olek pisze:z tego co zrozumiałem problemem są spacje w wartościach zmiennych
Tak, dokładnie - przepraszam jeśli nie napisałem wystarczająco jasno.

W końcu poradziłem sobie trochę na około wczytując cały output komendy do 1 zmiennej i potem przy każdym przejściu pętli for przepuszczając tą zmienną przez sed drukujący linię o numerze licznika pętli (+1)

Kod: Zaznacz cały

$(echo "${SNMPDescr}" | sed -n "$(( $count+1 ))p")
Narazie nie mam czasu zerknąć w tamten kod i poeksperymentować, ale dzięki olek za sugestie - popróbuję w wolnej chwili i dorzucę uwagi.

edit: literówki
Ostatnio zmieniony 2009-11-22, 02:08 przez kyan, łącznie zmieniany 1 raz.

ODPOWIEDZ