文件A包含此文本(假设“alpha”和“bravo”在一行上是任意长的块):
alpha {FOO} bravo
文件B包含任意数量的文本,包括各种古怪的字符。
我想将文件A中的字符串“{FOO}”替换为文件B的内容。使用sed的'r'命令如下所示不起作用,因为它在该行之后插入文件B的内容:
cat A | sed -e "/{FOO}/r B"
有没有办法,使用sed,最终得到一个包含以下内容的文件:
alpha [the contents of B] bravo
?如果使用perl更容易做到这一点,那也没关系。但我对perl的了解甚至比我对sed的了解更少。 ;)
答案 0 :(得分:2)
短perl
解决方案:
FOO="$( cat replacement.txt )" perl -pe's/\{FOO\}/$ENV{FOO}/g'
这适用于除00 NUL
之外的任何字符。如果必须处理二进制文件,可以使用:
perl -pe'
BEGIN {
open(my $fh, "<", shift(@ARGV)) or die $!;
local $/;
$FOO = <$fh>;
}
s/\{FOO\}/$FOO/g
' replacement.txt
用法:
perl -i~ -pe'...' file # In-place edit with backup
perl -i -pe'...' file # In-place edit without backup
perl -pe'...' file.in >file.out # Read from named file(s)
perl -pe'...' <file.in >file.out # Read from STDIN
答案 1 :(得分:1)
如果这是Linux上的Bash,这似乎有效:
sed -i "s/{FOO}/$(cat B.txt)/g" A.txt
这将直接编辑文件A.txt
- 它们不一定是.txt文件,我只是添加了这些文件以使其更明显。
正如@ikegami指出的那样,如果文件中有/
,则会出现问题 - 也可能会忽略任何\
。
因此,为了解决这个问题,您应该可以使用:
sed -i "s/\//%2F/g" B.txt
sed -i "s/{FOO}/$(cat B.txt)/g" A.txt
sed -i "s/%2F/\//g" B.txt
但您不必使用%2F
。
答案 2 :(得分:0)
#!/usr/bin/perl
use strict;
use warnings;
open my $fh_a, '<', $ARGV[0] or die "Failed to open $ARGV[0] for reading";
open my $fh_b, '<', $ARGV[1] or die "Failed to open $ARGV[1] for reading";
my $a;
my $b;
{
local $/;
$a = <$fh_a>;
$b = <$fh_b>;
}
close $fh_a;
close $fh_b;
$a =~ s/{FOO}/$b/;
print $a;
只要您的文件在内存中都适合两次,这应该没问题。 local $/;
将I / O系统置于'slurp'模式,只需一次操作即可读取整个文件。
用法:
perl replace_foo.pl fileA fileB