С помощью sed
or awk
или чего-либо еще, как заменить пустые строки, за которыми следует определенная строка (например, &
или \end{align}
), на эту строку (следовательно, &
или \end{align}
)?
В качестве примера приведем исходный файл (редактировать: менее двусмысленный пример):
The quick brown fox jumps over the sleazy dog.
Indeed, the quick brown fox jumps over the sleazy dog.
\begin{align}
& foo
& bar
\end{align}
The quick brown fox jumps over the sleazy dog.
Indeed, the quick brown fox jumps over the sleazy dog.
и вот что я хотел бы получить:
The quick brown fox jumps over the sleazy dog.
Indeed, the quick brown fox jumps over the sleazy dog.
\begin{align}
& foo
& bar
\end{align}
The quick brown fox jumps over the sleazy dog.
Indeed, the quick brown fox jumps over the sleazy dog.
решение1
GNU sed
с расширенной поддержкой регулярных выражений (-E) для облегчения написания регулярных выражений.
sed -Ei -e '
/./b
:a
$q;N
/\n$/ba
s/^\n+(&|\\(begin|end)\{align\})/\1/
' file
Идея заключается в том, чтобы начать собирать пустые строки и остановиться, когда будет обнаружена непустая строка. Затем регулярное выражение проверит, следует ли за фрагментом пустых строк одна из следующих трех строк:
- строка, начинающаяся с амперсанда
&
- строка, начинающаяся с \begin{align}
- строка, начинающаяся с \end{align}
Затем мы удаляем эти конкретные пустые строки.
решение2
В pcregrep
многострочном режиме:
pcregrep -M '^(?!\s+^(&|\Q\end{align}\E))' < file
grep на предмет начала строк, за которыми не следует один или несколько пробелов (включая новую строку), начала другой строки и wither &
или \end{align}
.
Или с perl
:
perl -0777 -pe 's/^\s+^(&|\Q\end{align}\E)/$1/gm' < file
решение3
Это удаляетвсепустые строки в блоке выравнивания:
sed '/\\begin/,/\\end/ { /^$/d; }' file
Точка с запятой требуется для BSD sed на моем Mac, но не для GNU sed.
Сложнее сопоставить конкретные типы блоков. Простой метод —
sed '
/\\begin{align}/,/\\end{align}/ { /^$/d; }
/\\begin{equation}/,/\\end{equation}/ { /^$/d; }
' file