Результат

Результат

У меня есть файлы (скажем, infile.tex) вида

AAAA
BBBB AAAA
CCCC BBBB AAAA

%%## Just some text
\begin{example}[foobar]
\begin{Sinput}
> set.seed(271)
> U <- runif(10)
> plot(U, 1-U)
\end{Sinput}
AAAA BBBB CCCC
\begin{Sinput}
> plot(qnorm(cbind(U, 1-U)))
\end{Sinput}
\end{example}

и я хотел бы извлечь все строки, начинающиеся с%%## ивсе линии между \begin{Sinput}и \end{Sinput}, поэтому

%%## Just some text
\begin{Sinput}
> set.seed(271)
> U <- runif(10)
> plot(U, 1-U)
\end{Sinput}
\begin{Sinput}
> plot(qnorm(cbind(U, 1-U)))
\end{Sinput}

Я пробовал работать с sed:

sed -n '/%%##\|\\begin{Sinput}/,/\\end{Sinput}/p' infile.tex# но также содержит\begin{example}[foobar]

sed -n '/^%%##\|\\begin{Sinput}/,/\\end{Sinput}/p' infile.tex# но не содержит строк, начинающихся с%%##

Примечание: Вышеизложенное в некоторой степени вытекает изэто здесь. Кроме того, возможно также «двухэтапное» решение (сначала извлечение всех строк, начинающихся с ..., а затем всех фрагментов) (я просто не понял, как это сделать, и, похоже, это sedпозволяет выбрать несколько «шаблонов», так что это выглядит более элегантно).

решение1

awkс его оператором диапазона (,) работает довольно хорошо для этого. Добавьте дополнительный фильтр в конце (;) и вуаля.

awk '/^\\begin\{Sinput\}/,/^\\end\{Sinput\}/;/^%%##/' infile.tex
%%## Just some text
\begin{Sinput}
> set.seed(271)
> U <- runif(10)
> plot(U, 1-U)
\end{Sinput}
\begin{Sinput}
> plot(qnorm(cbind(U, 1-U)))
\end{Sinput}

решение2

sed -e '/^\\begin{Sinput}/,/^\\end{Sinput}/!{/^%%##/!d}'

perl -lne 'print if /^\Q\begin{Sinput}/ .. /^\Q\end{Sinput}/ or /^%%##/'

Оператор rangeв Perl... Мы используем кавычки для следующего текста с помощью , \Qчтобы нам не нужно было явно экранировать специальные символы.

Результат

%%## Just some text
\begin{Sinput}
> set.seed(271)
> U <- runif(10)
> plot(U, 1-U)
\end{Sinput}
\begin{Sinput}
> plot(qnorm(cbind(U, 1-U)))
\end{Sinput}

Связанный контент