我与它斗争了很长时间,但现在我完全没有想法了。也许这里有人能帮助我。这是我想要实现的目标:
file_1.txt
:
# Some comment
some_variable="test"
some other things
# Marker
More things!@#$%^
file_2.txt
:
# Marker
# Some other comment
other_variable_1="test"
# Some totally other comment
other_variable_2="test"
我想插入file_2.txt
到file_1.txt
代替# Marker
,稍后我想反转这个过程。
最终文件file_1.txt
:
# Some comment
some_variable="test"
some other things
# Marker
# Some other comment
other_variable_1="test"
# Some totally other comment
other_variable_2="test"
More things!@#$%^
问题是,这两个文件都是多行的,并且包含各种特殊字符。我还想将这两个文件放在变量中。
我尝试了各种东西,sed、perl 和 awk。对我来说没有任何作用。我认为这是我最接近的尝试:
perl -pi -e 'chomp if eof' file_2.txt
marker_var="# Marker"
file_2_var=$(tr '\n' '\f' <file_2.txt)
sed -e "s|$marker_var|$file_2_var| tr '\f' '\n'" file_1.txt
我说最接近是因为它仍然不起作用。我尝试结合 stackexchange 的各种答案,但它会抛出有关未正确结束的错误s
。我怀疑这是因为\n
文件中的最后一个新行,所以我尝试使用 perl 命令删除它,但它不起作用。
有人可以帮帮我吗?
答案1
如果你已经有了 perl,那么就一直执行 perl:
open(f1,"<file_1.txt");
open(f2,"<file_2.txt");
open(out,">new_file_1.txt");
while(<f1>) {
last if /# Marker/;
print out;
}
print out while(<f2>);
print out while(<f1>);
close(out);
close(f1);
close(f2);
答案2
使用 awk 合并文件实际上很简单:
awk 'NR==FNR {if ($1 == "#" && $2 == "Marker") while((getline a<ARGV[2]) > 0) print a; else print}' file_1.txt file_2.txt > out
NR==FNR
这是一个 awk 技巧,用于确保我们只对第一个文件进行操作。检查这个回答以获取更多信息关于 NR 和 FNR{if ($1 == "#" && $2 == "Marker")else print}
# Marker
:解析第一个文件并输出所有行不是成立。while((getline a<ARGV[2]) > 0) print a;
解析ARGV[2]的内容(这里是file_2.txt)并输出。> out
是一个 shell 重定向,并将此命令的输出写入 out 文件中(如果该文件不存在,则创建该文件。
结果 :
$ awk 'NR==FNR {if ($1 == "#" && $2 == "Marker") while((getline a<ARGV[2]) > 0) print a; else print}' file_1.txt file_2.txt
# Some comment
some_variable="test"
some other things
# Marker
# Some other comment
other_variable_1="test"
# Some totally other comment
other_variable_2="test"
More things!@#$%^
答案3
使用sed
$ sed -Ee '/Marker/{e cat file_2.txt' -e ';d}' file_1.txt
# Some comment
some_variable="test"
some other things
# Marker
# Some other comment
other_variable_1="test"
# Some totally other comment
other_variable_2="test"
More things!@#$%^
答案4
使用任何 awk:
$ awk 'NR==FNR{new=new sep $0; sep=ORS; next} /# Marker/{$0=new} 1' file_2.txt file_1.txt
# Some comment
some_variable="test"
some other things
# Marker
# Some other comment
other_variable_1="test"
# Some totally other comment
other_variable_2="test"
More things!@#$%^
$ awk 'NR==FNR{new=new sep $0; sep=ORS; next} /# Marker/{$0=new} 1' file_1.txt file_2.txt
# Some comment
some_variable="test"
some other things
# Marker
More things!@#$%^
# Some other comment
other_variable_1="test"
# Some totally other comment
other_variable_2="test"
关于您问题中的脚本:
- 一旦您这样做,
tr '\n' '\f'
您就不再拥有有效的文本文件,因为它不再包含所需的终止换行符,因此 YMMVsed
或任何其他文本处理工具将对其进行处理。 - 当您的输入包含换页符时,将换行符映射到换页符的过程将会失败,就像在代码中的函数之间使用的那样,希望在打印时强制函数从新页面的顶部开始(或其他类似的文本)打印时需要在特定位置分页)。
- 你不能这样做,
sed -e "s|$marker_var|$file_2_var|
因为file_2_var
它本身可能包含|
s 或反向引用,例如&
sed\1
然后会解释,请参阅https://stackoverflow.com/q/29613304/1745001。