Как заменить пустые строки, за которыми следует определенная строка, на эту строку?

Как заменить пустые строки, за которыми следует определенная строка, на эту строку?

С помощью sedor 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

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