如何替换不同行上的两个模式之间的文本?

如何替换不同行上的两个模式之间的文本?

我有几个文件包含需要替换的文本。文本每次都以相同的模式开始和结束,但模式之间的内容是可变的。模式可以出现在行的中间,并且它们之间的内容通常跨越多行。

每个文件中只会出现一次开始和结束模式。

我需要一种命令行方法来替换模式之间的文本,包括模式本身。输出到新文件或就地编辑都可以。

对单个文件进行操作的命令可以工作,因为我可以循环遍历文件并自己应用命令。我尝试了一个sed解决方案,但只能替换整行。

文本示例如下:

Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin: 
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size: 
45mm, Security: Security-Start Bs86gKI-734Lw#32_nP/5589Zfb8Wj-
sW93j9b Security-End, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...

起始模式是Security-Start,结束模式是Security-End。我想用单词 替换模式和其间的所有内容REDACTED

我希望输出是:

Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin: 
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size: 
45mm, Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...

请注意,两个模式之间的文本可能很长,跨越几行,长度相当随机。这在上面的例子中并不明显

Ubuntu 系统默认提供的任何语言都可以。我首先想到的是“sed”或“awk”,但只要您觉得合适,都可以。

答案1

它应该对你有用:

sed -e '/Security-Start/{ N; s/Security-Start.*Security-End/REDACTED/ }'
  • /Security-Start/搜索“安全-开始”
  • 如果找到它:“N;”表示附加下一行。
  • s/Security-Start.*Security-End/REDACTED/并对最终结果进行替换。

对于两行以上,请使用以下一行:

sed -n '1h; 1!H; ${ g; s/Security-Start.*Security-End/REDACTED/p }'

这里

答案2

如果文件不是太大,那么你可以在啜饮模式

$ perl -0777 -pe 's/Security-Start.*Security-End/REDACTED/s' file 
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin: 
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size: 
45mm, Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...

命令-0777行参数有效地取消了记录分隔符的设置,以便整个文件被读取。s正则表达式修饰符使 perl 在 中包含换行符.,使表达式跨行匹配。


或者,使用 sed 循环:

$ sed '/Security-Start/ {:a; $!N; s/Security-Start.*Security-End/REDACTED/; t; ba}' file
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin: 
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size: 
45mm, Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...

使用 GNU sed,你可以将t; ba(成功替换后分支出;否则分支到:a)替换为Ta(成功替换后分支:a联合国替换成功)。

答案3

更手动的方法是用 NULL 替换输入文件中的所有换行符,使用简单的perl非贪婪正则表达式进行替换,然后将换行符放回:

$ tr '\n' '\0' < file | 
    perl -pe 's/Security-Start.*?Security-End/Security: REDACTED/g' |
        tr '\0' '\n'
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin: 
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size: 
45mm, Security: Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...

答案4

使用 awk 可以这样做:

awk -v RS='Security-Start.*Security-End' -v ORS= '1;NR==1{printf "REDACTED"}' file

相关内容