我有几个文件包含需要替换的文本。文本每次都以相同的模式开始和结束,但模式之间的内容是可变的。模式可以出现在行的中间,并且它们之间的内容通常跨越多行。
每个文件中只会出现一次开始和结束模式。
我需要一种命令行方法来替换模式之间的文本,包括模式本身。输出到新文件或就地编辑都可以。
对单个文件进行操作的命令可以工作,因为我可以循环遍历文件并自己应用命令。我尝试了一个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