Кредиты @dgig и @Paulo, которые помогли мне с их отзывами! Финальный perl
однострочник здесь:
perl -lne 'if(/FOO/../BAR/)' file
Объяснение:
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
Старый ответ:
Кредиты @Paulo для простого sed
решения. Это так же просто и легко прочитать в awk
:
awk '/FOO/,/BAR/' file
Однако это может быть слишком просто: он возвращает целые строки, а не точно «часть текста, начинающуюся при первом появлении FOO и заканчивающуюся при первом появлении BAR». Я считаю, что это означает, что FOO должно быть первым словом, а BAR - последним. Для того, чтобы сделать это, требуется более запутанный ответ. Позвольте мне попытаться сделать это в perl
.
Простой случай (возвращает целые строки):
perl -lne 'print if /FOO/../BAR/' file
Сложный случай (именно от FOO до BAR):
perl -lne 'if(/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if!$i++;$_=~s/BAR\K.*//;print}' file
Мне нравится это эквивалентное решение, которое присваивает переменную оператору диапазона:
perl -lne 'if($a=/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if$a==1;$_=~s/BAR\K.*// if$a=~/E/;print}' file
Примечание. Предполагается, что извлекается только одна часть текста, то есть мы не должны встречать другое FOO после первого абзаца, разделенного FOO и BAR.
В противном случае, простой случай уже не так прост в awk
:
awk '/FOO/,/BAR/ }' file
и в perl
:
perl -lne '(print&&/BAR/&&exit) if /FOO/../BAR/' file
И сложные, более изысканные решения становятся:
perl -lne 'if(/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if!$i++;$_=~s/BAR\K.*//&&print&&exit;print}' file
а также:
perl -lne 'if($a=/FOO/../BAR/){$_=~s/.*?(FOO)/$1/ if$a==1;$_=~s/BAR\K.*//&&print&&exit if$a=~/E/;print}' file
В этом примере показано, как однострочник может перейти от исключительно ясного и понятного к тому, что выглядит как неясная последовательность случайных символов, добавив немного больше сложности к проблеме. Везде, где это необходимо, я бы порекомендовал написать отдельный, поддерживаемый, читабельный сценарий, в котором можно легко добавлять дополнительные функции и учитывать все случаи.