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
如何将最后的额外文本包装在{
and中}
?
解决方案
使用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
推荐阅读
- java - 无论如何要创建一个 Spring Aspect 建议来触发任何未由某些注释注释的方法?
- angular - Angular - 在新应用程序中何时使用以及何时不使用 Angular
- sql - 长时间运行的函数在 PostgreSQL 中没有回复
- android - 我的 arcore pro throw 找不到“libarsceneview_jni.so”,有人可以帮助我吗?
- php - 验证码验证始终返回 true
- pandas - 将函数应用于熊猫数据框中的特定选定列
- javascript - 如何从
当值更改为其各自的标签时 | 验证 - sql - 将来自多个实体的数据存档在一个表中并形成报告的最佳实践
- django - Django - 如何使用视图执行删除对象
- python - 为什么相同的python re模式正则表达式在单行中有效,但在多行中无效