我看过下面的stackoverflow How to use regex for multiple line pattern in shell script,但它并不完全是我想要的。我正在寻找一种基于终端的方式来做一个就地sed
(或perl
)正则表达式,它将自动为我改变一些文件。(我可能可以用xml库/等来做,但我更喜欢使用终端)。
我手上的文件
Some text
<div class="firstClass secondClass" something="else">
Some random stuff
</div>
Random Text
<div class="thirdClass fifthClass" something="else">
Some random stuff
< is something
< but not /> This
</div>
<div class="fourthClass">
Some random stuff
</div>
Final Text
字符串
我试着做一个任意的例子来展示几个不同的用例。我试着把它转换成如下的东西:
Some text
<!-- firstClass start -->
Some random stuff
<!-- firstClass end -->
Random Text
<!-- thirdClass start -->
Some random stuff
< is something
< but not /> This
<!-- thirdClass end -->
<!-- fourthClass start -->
Some random stuff
<!-- fourthClass end -->
Final Text
型
我正在尝试以下代码:
sed -n '/<div class="\([^ "]*\)[^>]*>/,/<\/div>/{s/<div class="\([^ "]*\)[^>]*>/<!-- \1 start -->/;/<\/div>/d;p}' file
型
但是因为在前面的stackoverflow问题中,这个人不想要最后一行,所以答案删除了它,这不是我想要的。可以看出,我希望第一个文本在内部内容之前和之后重复。
上面的正则表达式正确地修复了第一行(将div更改为注解),但我似乎无法在文本下面复制它。我试图弄乱正则表达式,但我似乎无法让它工作。它还删除了第一行和最后一行,尽管我想保留它们。有什么想法可以做到这一点吗?
(PS是的,我知道我们需要sed -i
作为就地命令,但我想在实际运行它之前对其进行测试,原因很明显)
**Edit:**关于我想做的事情的想法的一个小补充。虽然上面是HTML,但这段代码不一定专门用于HTML(因此我不想要HTML/XML处理)。想法是:
Some random text before my pattern
PATTERN "info ...
random stuffs
END PATTERN
Some random stuff after pattern
型
我想把这个换成
Some random text before my pattern
NEW PATTERN - info
random stuffs
END NEW PATTERN - info
Some random stuff after pattern
型
所以不一定是html。只是一些在文本上有模式的东西,唯一的条件是random stuffs
不会有文本END PATTERN
,所以这就是我想要的基础。random stuffs
将100%永远不会有END PATTERN
文本。没有嵌套,也没有任何边缘情况。它总是与上面显示的模式相同。唯一的“边缘”情况是,第一行PATTERN "info ...
可能有一些额外的文本,直到我不关心的换行符。这可以 * 总是 * 被删除。我只关心单词info
(又名直到第一个空格字符或第一个"
字符)。
4条答案
按热度按时间jtjikinw1#
对于初学者来说,这里有一个简单的take,它在我对特定发布文本的测试中起作用
字符串
修改器为:
s
,这样.
也匹配一个换行符(通常它不匹配),x
,这样文字空间被忽略,这有助于可读性,g
,这样它就可以通过字符串,匹配和替换。我建议使用文件中的程序,而不是命令行程序(“一行程序”),但由于这是在这里的问题中特别要求的
型
-0777
开关使其将整个文件读入$_
变量,这是Perl中许多事情的默认值--在本例中是regex的s{}{}
运算符。在一个更大、更结构化的程序中,你可能会在变量中有开始和结束模式,
型
在这种情况下,
型
然而,如果这些模式变得复杂,
jvlzgdj92#
这可能对你有用(GNU sed):
字符串
匹配起始div。
将该行处理为所需的格式并制作副本。
打印/获取下一行,直到div结束。
将该行替换为副本,并将
start
替换为end
,然后打印结果。重复.
zpgglvta3#
在第一个例子中使用GNU awk的第三个arg to match()和强类型regexp常量:
字符串
型
型
对于你的第二个例子,我们只需要一个新的定义文件,但可以重用上面的
common.awk
:型
型
注意,我们只是在2个
defs*.awk
文件的BEGIN
部分中定义了所需的输入regexp和输出格式,我们没有更改common.awk
中的其余代码。所有这一切都取决于您可以在regexp中定义第一个捕获组,该捕获组与您的开始行匹配,以包含您希望在开始行和结束行中保留/打印的关键信息。对于endReg匹配,您并不严格需要
match()
,但我使用它是为了防止您将来需要调整它以用于其他结尾格式。只需将
awk
更改为awk -i inplace
,即可执行与所有其他工具相同的伪原地编辑。xmd2e60i4#
下面是一个简单的Awk脚本,它提取
class="
之后的第一个标记,并在替换文本中使用它。字符串
在正则表达式匹配方面,这里没有什么“多行”,只是一个简单的工具,用于记住行之间的一些状态。Awk仍然一次检查一行(尽管如果需要,也不难改变;参见
RS
)。