Skocz do zawartości

Jak Robic Zmiany W Pliku


nagardd

Rekomendowane odpowiedzi

Witam,

 

Mam plik ktory wyglada nastepujaca:

 

# cat save
Host: m1
Install type: gh1
Locale: C
Time Zone: US/Pacific

Host: m2
Install type: gh2
Locale: ja_JP.PCK
Time Zone: Japan

 

Nastepnie w skrypcie mam zmienne ktore sa pobierane od uzytkownika i moga miec takie wartosci:

 

HOST=m1

type=ble

locale=C

TZ=US

 

W zaleznosci od tego ktory to HOST skrypt powinien zmieniac tylko te wartosci ktore naleza do tego hosta.

 

Np. Jesli HOST=m1 to ma zmienic linie "Install type:", "Locale:", "Time Zone:" nalezace tylko do hosta m1.

Wpisy dla hosta m2 powinny byc nie zmienione.

 

Prosze o pomoc jak by mozna to zrobic w bashu.

Ja dopiero sie ucze wiec prosze o jakies wskazowki (nie koniecznie musza byc gotowe rozwiazania).

 

Pozdrawiam,

Daniel

Odnośnik do komentarza
Udostępnij na innych stronach

hmmm wiem z doświadczenia, iż czasami while okazywało się lepsze niż if...then... zaś for nieczęsto stosowałem ze względu na fakt, iż ciągle zapominałem składni...ale myślę, że dałoby radę tutaj to zrobić...

Wyglądałoby obrazowo mniej więcej tak (jeśli dobrze rozumiem Twój post)

for HOST=m1 ->* Install type=(cośtam) && Locale=(cośtam) && Time Zone=(cośtam)

 

* - strzałka użyta do pomocy w zobrazowaniu

 

Ogółem składnia for dla DS'a pamiętam zawierała się w jednym nawiasie a czy tak samo tutaj...niby te instrukcje warunkowe są dosyć uniwersalne ale nie dam głowy

Myślę też, że na upartego i while zadziałałoby...

Odnośnik do komentarza
Udostępnij na innych stronach

Przyznaje sie ze nie wiem jak to zrobic.

Do zamany stringow uzywam sed'a ale sed zamienia wszystkie stringi o takiej samej nazwie w pliku.

Moj skrypt wyglada tak ale "Install type" jest zamieniane wszedzie.

 

#!/bin/bash

HOST=m1
type=ble
locale=C
TZ=US

        if [ `sed -n "/$HOST/p" save |awk '{print $2}'` = $HOST ]
        then
                sed "s/Install type:.*/Install type: $type/" save > save.tmp
                mv save.tmp save
        else
        exit 0
        fi

 

Prosze o pomoc.

Odnośnik do komentarza
Udostępnij na innych stronach

Moj skrypt wyglada tak ale "Install type" jest zamieniane wszedzie.
możesz np. liczyć linie, dowiedzieć się w ten sposób gdzie jest interesujacą Cię sekcja i wymienić string tylko w określonej linii. W podanym pliku przy założeniu, że te same wartości wypadają co 5 linii (czyli zawsze w tej samej kolejności) nie powinno być to zbyt trudne, bo np. linia zaczyna się od "Host: ", więc sprawdzasz co jest w tej linii za 6 znakiem (powinna być interesujaca Cie nazwa). Powiedzmy, że trafiłeś na m2 (linia 6. czyli licznik=6) więc tak na szybko to mi coś takiego wyszło:

#!/bin/bash

   exec<${1}
   value=0
   sekcja=""
   while read line
   do
     value=`expr $value + 1`;
     sekcja=`echo ${line}|grep "Host"`
     if [ "x${sekcja}" != "x" ]; then
       if [ X`echo "${sekcja:6}"` == X${2} ]; then
         licznik=`expr $value + 1`
         sed "${licznik}s/Install type:.*/Install type: $type/" $1 > save.tmp
       fi
     fi
   done

Parametry wejściowe pliku chyba oczywiste: $1 - nazwa pliku wejsciowego ("save"), $2 - szukana sekcja (m1, m2, ...), $3 - docelowy "install type"

Czyli wywołanie np.

skrypt.sh save m2 nowy_gh2

Jakby to dopieścić, to pewnie ładniej można by było napisać.

 

Odnośnik do komentarza
Udostępnij na innych stronach

Do zamany stringow uzywam sed'a ale sed zamienia wszystkie stringi o takiej samej nazwie w pliku.

Niekoniecznie, sed zaiste potężny jest ;)

Oto przykład:

[ecik@ecik ~/tmp]$ cat save
Host: m1
Install type: gh1
Locale: C
Time Zone: US/Pacific

Host: m2
Install type: gh2
Locale: ja_JP.PCK
Time Zone: Japan

Host: m3
Install type: gc3
Locale: abc
Time Zone: Pole-land

[ecik@ecik ~/tmp]$ sed "/Host: m1/,/Host/s#\(Install type:\).*#\1 bla#" save
Host: m1
Install type: bla
Locale: C
Time Zone: US/Pacific

Host: m2
Install type: gh2
Locale: ja_JP.PCK
Time Zone: Japan

Host: m3
Install type: gc3
Locale: abc
Time Zone: Pole-land

[ecik@ecik ~/tmp]$ sed "/Host: m2/,/Host/s#\(Install type:\).*#\1 bla#" save
Host: m1
Install type: gh1
Locale: C
Time Zone: US/Pacific

Host: m2
Install type: bla
Locale: ja_JP.PCK
Time Zone: Japan

Host: m3
Install type: gc3
Locale: abc
Time Zone: Pole-land

 

Aby zrozumieć jak to działa polecam zajrzeć do info sed (albo lepiej pinfo sed ;)) do sekcji Addresses - Selecting lines with sed.

Odnośnik do komentarza
Udostępnij na innych stronach

Dzieki za pomoc.

Jednak nie bardzo rozumiem jaka funkcje w skrypcie spelniaja znaki "x" i "X"?

 

if [ "x${sekcja}" != "x" ]; then
       if [ X`echo "${sekcja:6}"` == X${2} ]; then

 

O ile w perwszej linii jeszcze moge sie domyslac ze jezeli ${sekcja} jest puste to x = x ale w drugiej juz nie rozumiem po co to jest.

Sorry za takie pytanie :)

Odnośnik do komentarza
Udostępnij na innych stronach

O ile w perwszej linii jeszcze moge sie domyslac ze jezeli ${sekcja} jest puste to x = x ale w drugiej juz nie rozumiem po co to jest.

X`echo "${sekcja:6}"` - zawartość linii (zmiennej sekcja) od 6. znaku czyli "odcięcie" stringa "Host: ". Pozostaje nazwa hosta: m1, m2, ...

${2} - to chyba oczywiste: nazwa hosta podana jako parametr skryptu

 

iksy (lub dowolna inna literka) dodawane są dlatego, że w pewnych szczególnych sytuacjach porównanie pustych łańcuchów może dać błędny wynik a nawet wstrzymać wykonanie skryptu. Nie podam w tej chwili przykładu, ale na pewno znajdziesz dokładne wyjaśnienie jak poszukasz.

 

Tak czy inaczej to co podał ecik__ jest zdecydowaniej bardziej eleganckim rozwiązaniem i zapewne - wbrew pozorom - bardziej czytelnym.

 

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...