Dank an @dgig und @Paulo, die mir mit ihrem Feedback geholfen haben! Letzter perl
Einliner hier:
perl -lne 'if(/FOO/../BAR/)' file
Erläuterung:
if(/FOO/../BAR/){ # perform the following actions on each line, starting # with a line that contains FOO, and up to and including # a line that contains BAR s/.*?(FOO)/$1/ if!$i++; # only on the first line that contains FOO, # delete all characters before FOO s/BAR\K.*//&&print&&exit;# if the line contains BAR, remove characters # after BAR, print the line and stop processing print # simply print the line contents
Alte Antwort:
Dank an @Paulo für eine einfache sed
Lösung. Es ist genauso einfach und leicht zu lesen awk
:
awk '/FOO/,/BAR/' file
Es könnte jedoch zu einfach sein: Es werden ganze Zeilen zurückgegeben und nicht genau "ein Textabschnitt, der beim ersten Auftreten von FOO beginnt und beim ersten Auftreten von BAR endet". Ich glaube, dass bedeutet, dass FOO das erste Wort und BAR das letzte Wort sein sollte. Genau das zu tun, erfordert eine kompliziertere Antwort. Lassen Sie mich versuchen, das zu erreichen perl
.
Einfacher Fall (gibt ganze Zeilen zurück):
perl -lne 'print if /FOO/../BAR/' file
Komplexer Fall (genau von FOO bis BAR):
perl -lne 'if(/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if!$i++;$_=~s/BAR\K.*//;print}' file
Ich mag diese gleichwertige Lösung, die dem Bereichsoperator eine Variable zuordnet:
perl -lne 'if($a=/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if$a==1;$_=~s/BAR\K.*// if$a=~/E/;print}' file
Hinweis: Es wird davon ausgegangen, dass nur ein Teil des Textes extrahiert werden muss, dh, wir sollten nach dem ersten Absatz, der durch FOO und BAR begrenzt ist, keinen anderen FOO antreffen.
Ansonsten ist der einfache Fall schon nicht mehr so einfach in awk
:
awk '/FOO/,/BAR/ }' file
und in perl
:
perl -lne '(print&&/BAR/&&exit) if /FOO/../BAR/' file
Und die komplexen, verfeinerten Lösungen werden zu:
perl -lne 'if(/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if!$i++;$_=~s/BAR\K.*//&&print&&exit;print}' file
und:
perl -lne 'if($a=/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if$a==1;$_=~s/BAR\K.*//&&print&&exit if$a=~/E/;print}' file
Dieses Beispiel zeigt, wie ein Einzeiler außergewöhnlich klar und selbsterklärend werden kann, was zu einer obskuren Folge von zufälligen Zeichen führt, da er dem Problem nur etwas mehr Komplexität hinzugefügt hat. Wo immer nötig, würde ich empfehlen, ein eigenständiges, wartbares, lesbares Skript zu schreiben, in dem zusätzliche Funktionen leicht hinzugefügt und Eckfälle berücksichtigt werden können.