Ich habe Dateien (sagen wir, infile.tex
) der Form
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}
und ich möchte alle Zeilen extrahieren, die beginnen mit%%##
Undalle Zeilen zwischen \begin{Sinput}
und \end{Sinput}
, also
%%## 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}
Ich habe versucht, mit Folgendem zu arbeiten sed
:
sed -n '/%%##\|\\begin{Sinput}/,/\\end{Sinput}/p' infile.tex
# enthält aber auch\begin{example}[foobar]
sed -n '/^%%##\|\\begin{Sinput}/,/\\end{Sinput}/p' infile.tex
#, enthält aber keine Zeilen, die mit beginnen%%##
Hinweis: Das Obige ist teilweise abgeleitet vondas hier. Auch eine „Zwei-Schritt-Lösung“ (zuerst alle Zeilen extrahieren, die mit ... beginnen, und dann alle Blöcke) könnte möglich sein (ich habe nur nicht gesehen, wie das geht, und es scheint, als ob man sed
mehrere „Muster“ auswählen kann, was eleganter erscheint).
Antwort1
awk
mit seinem Bereichsoperator (,) funktioniert hierfür ziemlich gut. Fügen Sie am Ende einen zusätzlichen Filter hinzu (;) und presto.
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}
Antwort2
sed -e '/^\\begin{Sinput}/,/^\\end{Sinput}/!{/^%%##/!d}'
perl -lne 'print if /^\Q\begin{Sinput}/ .. /^\Q\end{Sinput}/ or /^%%##/'
Der range
Operator in Perl
ist ..
. Wir verwenden das Anführungszeichen für den folgenden Text, \Q
damit wir die Sonderzeichen nicht explizit maskieren müssen.
Ergebnis
%%## 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}