将“\n”更改为“|”使用 sed 在 2 个模式(排除模式)之间

将“\n”更改为“|”使用 sed 在 2 个模式(排除模式)之间

我想将 \n 更改为 |使用 sed 在 2 个模式(排除模式)之间。

我有一个包含多次地址序列的文件:

Adress:
1540 Broadway
New York
NY 10036
United-states
###

我想得到:

Adress:1540 Broadway|New York|NY 10036|United-states
###

我使用以下行代码:

sed -i "/^Adress:/!b;:a;/###/bb;$!{N;ba};:b;s/\n/\|/g;tb" file.txt

...但它包括两种模式,我得到了这个错误的结果:

Adress:|1540 Broadway|New York|NY 10036|United-states|###

如何更改它以从替代品中排除模式?

答案1

不建议使用循环来完成此类工作,除非您正在处理一个小问题。行数1 .您最好使用范围和保留空间:

sed '/Address/,/###/{
/###/!H;/Address/h;/###/!d;x;s/\n//;s/\n/|/g;G
}' infile

也就是说,对于该范围中的每一行,执行以下操作:如果它不是范围中的最后一行,则追加到保留空间(如果是范围中的第一行则覆盖)并删除该行,否则交换缓冲区,删除第一个嵌入的换行符并将其余的替换为|.然后将保持缓冲区内容附加到模式空间。
如果最后一个后面Address没有跟随着,那么这将失败###,所以为了避免这种情况,请使用第二个条件,并且仅当它不是输入的最后一行时才删除,否则追加到保存缓冲区,交换并退出:

sed '/Address/,/###/{
/###/!H;/Address/h;/###/!{
$!d;H;x;q
}
x;s/\n//;s/\n/|/g;G
}' infile

1:您必须拉入的行越多,速度就越慢,因为需要不断检查模式空间是否匹配 - 请参阅结果在这里(我知道这是一个不同的要求,但只是为了给你一个想法......)

相关内容