我有类似的指令,就像在线程中一样打印匹配行和匹配行中的第 n 行
我需要匹配特定行,打印它,然后删除以下行(以下第一行),然后打印其余行,直到匹配特定行等。
换句话说,我只需要删除以</s>
开头的行后面的行<doc
。
我的文件:
<doc>
</s>
<s>
Bla
bla
bla
.
</s>
<s>
Bla
bla
bla
.
</s>
</doc>
<doc>
</s>
...
我所需的输出:
<doc>
<s>
Bla
bla
bla
.
</s>
<s>
Bla
bla
bla
.
</s>
</doc>
<doc>
...
答案1
sed
有了基础知识,这个问题就不难理解了:
sed '/<doc>/{n;/<\/s>/d;}'
对于带有 的行<doc>
,打印它并用 读取下一行n
,然后,如果下面的行包含</s>
(斜线需要转义),则用 删除它d
。
更详细的解释:/expression/{command;command;...;}
意味着仅在与模式匹配的行上执行命令,因此所有其他行都会按原样打印,而对于该<doc>
行,n
则会执行。该命令打印当前行并读取下一行,因此以下命令将在下一行执行。这里又出现了另一个d
带有“地址”( ) 的命令 ( ),因此只有包含 的/<\/s>/
行才会被删除,否则将被打印。无论哪种情况,脚本都会继续执行以下行。d
</s>
答案2
使用 GNU sed
:
sed -z -i 's:<doc>\n</s>:<doc>:g' infile.txt
这将<doc>
后面的替换</s>
为 only <doc>
。sed
's标志-i
用于就地替换;并且该g
标志将替换全部的发生。-z
导致用 NULL 字符分隔行。
答案3
正如你所标记的,shell_script
我建议awk方法:
awk '/^<doc>/ && getline nl > 0 && nl!~/^<\/s>/{ print $0 RS nl }1' file
输出:
<doc>
<s>
Bla
bla
bla
.
</s>
<s>
Bla
bla
bla
.
</s>
</doc>
<doc>
...