Rog*_*man -1 sed awk perl text-processing
我有三个文件,main.txt
,out.txt
和in.txt
. 我想用 的内容替换每次出现的out.txt
inmain.txt
内容in.txt
。
和out.txt
都in.txt
可以包含多行和各种特殊字符。如何正确读取和转义这些字符串?
这是一个包含一些边缘情况的示例,例如特殊字符、重复匹配、不完整匹配、重叠匹配。
main.txt
:
foo
Replace these
three lines
with some $.*\'"& in it
bar
Replace these
three lines
with some $.*\'"& in it
Replace these
three lines
with some $.*\'"& in it
three lines
Replace these
three lines
three lines
with some $.*\'"& in it
baz
Run Code Online (Sandbox Code Playgroud)
out.txt
:
Replace these
three lines
with some $.*\'"& in it
Run Code Online (Sandbox Code Playgroud)
in.txt
:
Replacement lines
also with $.*\'"&
Run Code Online (Sandbox Code Playgroud)
预期输出:
foo
Replacement lines
also with $.*\'"&
bar
Replacement lines
also with $.*\'"&
Replacement lines
also with $.*\'"&
three lines
Replace these
three lines
three lines
with some $.*\'"& in it
baz
Run Code Online (Sandbox Code Playgroud)
和perl
:
perl -0777 -e \'$out = <>; $in = <>; $_ = <>; s/\\Q$out\\E/$in/g; print\n \' out.txt in.txt main.txt > new-main.txt\n
Run Code Online (Sandbox Code Playgroud)\n应该适用于文件可能包含的任何字符或非字符(也适用于二进制文件),只要它们足够小以适合内存。
\n-0777
将输入记录分隔符设置为不可能的值,与执行相同$/ = undef
,因此<>
依次从作为参数传递的 files\xc2\xb9 读取整个文件。
所以我们有//$out
分别包含、和的完整内容。$in
$_
out.txt
in.txt
main.txt
$_
s/pattern/replacement/flags
是运算符默认处理并默认打印的变量print
,相当于中的模式空间sed
。
这里的模式是导致内部内容被按字面处理,而不是作为正则表达式处理的\\Q$out\\E
地方。\\Q...\\E
该g
标志将替换所有出现的情况,如 中的情况sed
。
\xc2\xb9 或命令输出,例如ls|
, 使用<<>>
这些命令输出仅解释为文件路径