sed - 替换字符串,但仅当该字符串在特定行之前最后一次出现时

标签 sed

我正在将自定义标记语言转换为 TeX。
我有一个这样的文件:

\macro{stuff}
{more stuff}
{yet other stuff}
{some stuff}
these are extra lines
another extra line
there can be any number of extra lines
e

\macro{yet more stuff stuff}
{even more stuff}
{yet other stuff}
{some stuff}
this is extra
this is extra too
e
我需要的结果是这样的:
\macro{stuff}
{more stuff}
{yet other stuff}
{some stuff}{
these are extra lines
another extra line
there can be any number of extra lines
}

\macro{yet more stuff stuff}
{even more stuff}
{yet other stuff}
{some stuff}{
this is extra
this is extra too
}
通知e单独在一行上,表示一组数据的结尾,它只是被一个右括号替换。
我可以简单地使用这个:
sed -i 's/^e$/}/g' file.tex
结果是这样:
\macro{stuff}
{more stuff}
{yet other stuff}
{some stuff}
these are extra lines
another extra line
there can be any number of extra lines
}

\macro{yet more stuff stuff}
{even more stuff}
{yet other stuff}
{some stuff}
this is extra
this is extra too
}
问题是,我还需要一个匹配的起始括号来包围 e 之前的这个额外文本。 .
一种思考方式是:
  • 替换每次出现的 } .
  • 但前提是该事件位于行尾。
  • 并且仅当它是出现在 e 之前的最后一次出现时完全自己出现。

  • 这是我能想到的最接近的,不知道如何匹配不包含更多 }$ 匹配项的任意数量的行:
    sed -i 's/}$\n.*\n.*\n.*\n^e$/}{&}/g' file.tex
    
    我如何将最后的额外文本包裹在 { 中和 } ?

    最佳答案

    使用 awk 更容易做到这一点使用空 RS .这是一个 gnu-awk解决方案:

    awk -v RS= '{sub(/.*}/, "&{"); sub(/\ne$/, "\n}"); ORS=RT} 1' file
    
    \macro{stuff}
    {more stuff}
    {yet other stuff}
    {some stuff}{
    these are extra lines
    another extra line
    there can be any number of extra lines
    }
    
    \macro{yet more stuff stuff}
    {even more stuff}
    {yet other stuff}
    {some stuff}{
    this is extra
    this is extra too
    }
    
    或任何版本的 awk :
    awk -v RS= '{sub(/.*}/, "&{"); sub(/\ne$/, "\n}\n")} 1' file
    

    关于sed - 替换字符串,但仅当该字符串在特定行之前最后一次出现时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68473178/

    相关文章:

    regex - 计算正则表达式通配符匹配的字符串中特定字符的匹配次数

    linux - 使用 AWK 添加选项卡时出现问题

    linux - sed move 一行

    awk - 在 text.file 中切换列

    sed - 替换 !使用 sed 导致找不到事件

    linux - 使用正则表达式修改文本文件

    对多个目录中的多个文件进行 sed

    windows - GNU sed - 查找或替换空格或新行。为什么这不起作用? v3.02 与 v4.2

    linux - 复制一个文件夹中多个文件中的文本

    regex - 用 SED 或 AWK(或其他有效的方法)替换日期 - Linux 正则表达式