Jeśli szukasz szybkiego rozwiązania w linii poleceń używając perla, jest to idealne rozwiązanie dla operatora flip-flop
. Obecnie istnieją dwa sposoby, które na to pytanie może być interpretowany w przypadkach krawędziowych - oba te będą funkcjonować tak samo długo jak pattern1
przychodzi przed pattern2
:
Jeśli wzorzec1 przychodzi po pattern2 ale przed pattern3 usuwać wszystko pomiędzy wzorzec1 i pattern3
lub, jeśli pa ttern1 przychodzi po pattern2 ale przed pattern3 zrobić nic chyba zobaczysz kolejny wzorcowi1.
Zanim zaczniemy, zwróć uwagę na arguement perl -p
-n assume "while (<>) { ... }" loop around program
-p assume loop like -n but print line also, like sed
Teraz do pierwszego, dam ci ..
perl -pe'$x ||= /7/; $_= "" if /5/ .. /8/ and $x' <(seq 1 10)
1
2
3
4
5
6
9
10
$x ||= /7/
: Ustawia $x
do wartość zwracana /7/
, gdy $x
jest . /7/
zwróci true
po dopasowaniu. Oznacza to, że $x
zostaje ustawione na true, w pierwszym dopasowaniu i natura ||=
nigdy nie ustawia zmiennej, kiedy jest już prawdą.
Następnie ustawia $_ = ''
, jeśli zakres zawiera się między /5/
i /8/
, a ustawiono już wartość true dla $x
. Zapamiętaj sposób działania zwarcia: a && b
oznacza, że uruchamiasz b
tylko wtedy, gdy a
ocenia na true
.W tym przypadku sam fakt oceny a
ustawi stan operatora flip-flop - tego właśnie chcemy; jednak chcemy tylko, aby wystąpił $_ = ''
, jeśli był już widziany 7
.
Teraz do drugiej interpretacji quesiton tylko zmienić kolejność ...
perl -pe'$x ||= /7/; $_= "" if $x and /5/ .. /8/' <(seq 1 10)
To wydrukować pełny zakres. Perl nie zacznie szukać /5/
dopóki nie znajdzie /7/
. W naszym zakresie sekwencyjnym to się nie stanie.
BTW, naprawdę umieścić niektóre z tych odpowiedzi do wstydu, wiele pomieszczeń nie są wymagane ...
perl -pe'$x||=/2/;$_=""if$x&&/5/../8/' # secksey
Jeśli wzorzec1 ** ** ** przychodzi po pattern2 ** powinno nastąpić usunięcie? –