首页 > 解决方案 > Linux bash:如何根据另一行/不同行上的模式替换一行上的字符串?

问题描述

我有一个包含以下数据的文件:

GS*PO*112233*445566*20211006*155007*2010408*X*004010~

ST*850*0001~
BEG*00*DS*A-112233**20211005~
REF*K6*Drop Ship Order~
REF*ZZ*SO168219~
REF*DC*ABC~

ST*850*0002~
BEG*00*DS*A-44556**20211005~
REF*K6*Drop Ship Order~
REF*ZZ*PO54361~

ST*850*0003~
BEG*00*DS*A-12345**20211005~
REF*K6*Drop Ship Order~
REF*DC*XYZ~
REF*ZZ*SO897654~

为清楚起见,我在每行上方插入了空白ST*850行。这是我想做的事情:

  1. 搜索模式REF*ZZ*SO
  2. 如果找到,则将前ST*850一行替换为ST*850C

所以生成的文件看起来像这样:

GS*PO*112233*445566*20211006*155007*2010408*X*004010~

ST*850C*0001~
BEG*00*DS*A-112233**20211005~
REF*K6*Drop Ship Order~
REF*ZZ*SO168219~
REF*DC*ABC~

ST*850*0002~
BEG*00*DS*A-44556**20211005~
REF*K6*Drop Ship Order~
REF*ZZ*PO54361~

ST*850C*0003~
BEG*00*DS*A-12345**20211005~
REF*K6*Drop Ship Order~
REF*DC*XYZ~
REF*ZZ*SO897654~

这是我尝试过的:

sed -i -n '/^REF\*ZZ\*SO/!{x;s/ST\*850\*/ST\*850C\*/;x};x;1!p;${x;p}' file

这将替换所有ST*850三行,ST*850C而不仅仅是第一和第三行。我究竟做错了什么?

标签: linuxbashsed

解决方案


这可能对您有用(GNU sed):

sed '/ST\*850/{:a;/REF\*ZZ\*SO/!{N;ba};s/.*ST\*850/&C/}' file

如果一行包含ST*850.

在匹配包含REF*ZZ*SO使用贪婪附加C到最新ST*850字符串的行时。

注意 regexp.*确保匹配将从集合的末尾而不是集合的开头回溯。


推荐阅读