使用sed将文件读入行的中间位置

时间:2014-02-25 18:08:50

标签: perl sed

文件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的了解更少。 ;)

3 个答案:

答案 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