Neguj warunek pętli while w bash


25

W części skryptu, nad którym pracuję, chcę sprawdzić, czy wprowadzony adres IP ma poprawny format. Chcę zrobić pętlę, gdy format wejściowy NIE jest poprawny. Poniższe działa dla pętli, gdy format jest poprawny.

while  [[  $range =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]
      do

Jak mogę to odwrócić, żeby powiedzieć, że NIE pasuje do formatu. Miałem nadzieję, !=~że zadziała, ale dostaję błąd składniowy.


2
Synner, jedna uwaga: chociaż jasne jest, że piszesz skrypt interaktywny, ogromna moc skryptowania powłoki wynika z możliwości robienia tego samego z tym samym skryptem zarówno interaktywnie, jak i w trybie wsadowym. W przyszłości będzie zdecydowanie łatwiej (kiedy zaczniesz używać skryptu jako bloku konstrukcyjnego), aby po prostu wprowadzić opcje w wierszu poleceń i natychmiast powrócić z niezerowym kodem wyjścia (i komunikatem), jeśli coś jest nie tak. Tylko moje 2 centy ...
Deer Hunter

Odpowiedzi:


60

Rozwiązanie jest takie proste, jestem pewien, że wszystkim się spodoba.

Nie musisz się zastanawiać nad szczegółami składni negacji, po prostu użyj untilzamiast while.


9

Do porównania łańcucha należy użyć !=zamiast !=~.

Z man bash

string1 != string2
          True if the strings are not equal.

Ponieważ używasz wyrażenia regularnego po prawej stronie, naprawdę potrzebujesz =~. Możesz zdecydować o zanegowaniu całego wyrażenia.

while  [[  !( $range =~ ^[0-9]{1,3]}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ) ]]

Przykład:

$ bash --version | head -n1
GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)
$ cat script
range='1'; while [[ !( $range =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ) ]]; do echo "$range NOT OK"; range+='.2'; sleep 1; done
echo "Finished"
$ bash script
1 NOT OK
1.2 NOT OK
1.2.2 NOT OK
Finished
$ 

Dziękuje za szybkie odpowiedzi. Próbowałem tego przed opublikowaniem i nie sprawdza się to poprawnie. Wydaje się, że ~ musi również działać poprawnie podczas sprawdzania, czy NIE pasuje do formatu.
Synner

@Synner Sprawdź zmianę
Bernhard

Nie działa z bash4.2.42. pastebin.com/0vHh5MMB
manatwork

1
@manatwork Wypróbuj w nieinteraktywnej powłoce.
Bernhard

@manatwork Zobacz moją edycję
Bernhard
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.