我正在开发一个bash补丁来对纯文本文件执行多项操作,以帮助减少多个Web服务器上的手动编辑。超出我的sed知识范围的一部分是如何编辑多次出现的字符串,仅编辑其中一个特定事件。以下面的编辑HTML为例:
<div class="dashlet">
<div class="body">
<div class="detail-list-item">
<!-- some content here -->
</div>
<div class="detail-list-item">
<!-- some more content here -->
</div>
<div class="detail-list-item">
<!-- some more content here -->
</div>
<div class="detail-list-item">
<!-- some more content here -->
</div>
<div class="detail-list-item last-item">
<!-- some final content here -->
</div>
</div>
</div>
我需要摆脱最后一段代码,虽然不太理想,因为这个文件可能会在将来的更新中发生变化,但我使用以下命令按行删除内容
sed -i '29,33d' /path/to/file
其中29是<div class="detail-list-item last-item">
所在的行,33是相应的结束</div>
标记。有没有更好的方法来防止此文件的未来更新版本,以便我不必检查文件以确保我没有删除错误的行?
最后一部分是我需要替换以前的html类以包含last-item
作为第二类。所以最终的html将类似于:
<div class="dashlet">
<div class="body">
<div class="detail-list-item">
<!-- some content here -->
</div>
<div class="detail-list-item">
<!-- some more content here -->
</div>
<div class="detail-list-item">
<!-- some more content here -->
</div>
<div class="detail-list-item last-item">
<!-- some final content here -->
<!-- note how we are one div shorter and this div's class has a second class -->
</div>
</div>
</div>
什么sed命令可以完成这项任务?
答案 0 :(得分:2)
由于sed逐行处理文件,因此它可能不是最佳解决方案。但是,由于您的文件非常小,您可以使用这种有点hacky的解决方案,将整个文件放入保留缓冲区,然后立即对整个文件执行替换:
sed -rni 'H;${x;s/\n(.*list-item)(".*)\n <div.* <\/div>/\1 last-item\2/p}' /path/to/file
以下是解释:
# options: -r extended regex so parentheses don't need to be escaped
# -n don't automatically print pattern space
# -i edit file in place
H; # add the current line to the hold space
$ # if we are at the last line
{ # commands until '}' are only run if at the last line
x; # swap pattern space and hold space
s/ # search/replace
\n(.*list-item) # greedy match to the last 'list-item', put in group 1
(".*) # double quote must follow 'list-item', match as many
# characters as possible and put in group 2
\n <div.* <\/div> # match all of the next (final) double-indented
# div, don't put it in a group
/
\1 last-item\2 # insert ' last-item' before groups 1 and 2, final
# double-indented div will be deleted
/p # print the result
}
您可以使用更简单的命令执行删除最终div的部分:
sed -i '/<div.*last-item/,/<\/div>/d' /path/to/file
不幸的是,我不知道将last-item
作为第二个类添加到最后一个div的简单方法。