将某些标记替换为文件内容(使用bash-script)

时间:2010-12-07 16:47:33

标签: bash sed awk replace

我的文件包含一些文字以及INSERT_HERE1INSERT_HERE2字样。我想分别用file1.txtfile2.txt的内容替换这些字词。

我怀疑sedawk可能会将其关闭,但我基本上从未使用它们。

7 个答案:

答案 0 :(得分:8)

Sed确实有一个内置的读取文件命令。你想要的命令看起来像这样:

$ sed -e '/INSERT_HERE1/ {
r FILE1
d }' -e '/INSERT_HERE2/ {
r FILE2
d }' < file

这将输出

foo
this is file1
bar
this is file2
baz

r命令读取文件,d命令删除带有INSERT_HERE标记的行。因为sed命令必须从它们自己的行开始,所以你需要使用大括号命令和多行输入的大括号,并且根据你的shell,你可能需要在行的末尾\以避免过早执行。如果这是你会经常使用的东西,你可以把命令放在一个文件中并使用sed -f来运行它。

答案 1 :(得分:4)

如果你对Perl没问题,你可以这样做:

$ cat FILE1
this is file1

$ cat FILE2
this is file2

$ cat file
foo
INSERT_HERE1
bar
INSERT_HERE2
baz

$ perl -ne 's/^INSERT_HERE(\d+)\s+$/`cat FILE$1`/e;print' file
foo
this is file1
bar
this is file2
baz
$ 

答案 2 :(得分:1)

这未经过测试,但与您的需求非常接近:

sed -e "s/INSERT_HERE1/`cat file1.txt`/" -e "s/INSERT_HERE2/`cat file2.txt`/" <file >file.out

但它无法正确处理带有斜杠的文件,因此您可能需要对其进行一些调整。

但是,我会推荐Perl。像这样:

#!/usr/bin/perl -w

my $f1 = `cat file1.txt`;
my $f2 = `cat file2.txt`;

while (<>) {
    chomp;
    s/INSERT_HERE1/$f1/;
    s/INSERT_HERE2/$f2/;
    print "$_\n";
}

这假设INSERT_HERE1和INSERT_HERE2每行只出现一次,并且file1.txt不包括文本INSERT_HERE2(虽然不难修复)。使用方式如下:

./script <file >file.out

答案 3 :(得分:1)

这适用于可以多次替换的小型替换文件:

awk 'BEGIN {
        while ((getline line < ARGV[1]) > 0) {file1 = file1 nl line; nl = "\n"}; 
        close (ARGV[1]); nl = "";
        while ((getline line < ARGV[2]) > 0) {file2 = file2 nl line; nl = "\n"};
        close (ARGV[2]);
        ARGV[1] = ""; ARGV[2] = "" }
      { gsub("token1", file1); 
        gsub("token2", file2); 
        print }' file1.txt file2.txt mainfile.txt

您可能希望在此处添加一些额外的换行符,具体取决于您希望输出的外观。

答案 4 :(得分:1)

轻松完成Bash。如果您需要它是POSIX shell,请告诉我:

#!/bin/bash

IFS=  # Needed to prevent the shell from interpreting the newlines
f1=$(< /path/to/file1.txt)
f2=$(< /path/to/file2.txt)

while read line; do 
  if [[ "$line" == "INSERT_HERE1" ]]; then
     echo "$f1"
  elif [[ "$line" == "INSERT_HERE2" ]]; then
     echo "$f2"
  else
     echo "$line"
  fi
done < /path/to/input/file

答案 5 :(得分:1)

此代码段替换了上部数组中指定的任何部分。对于例如这里

<!--insert.txt-->

,内容为“insert.txt”

#!/bin/bash

replace[1]=\<!--insert.txt--\>      ; file[1]=insert.txt
replace[2]=\<!--insert2.txt--\>     ; file[2]=insert2.txt

replacelength=${#replace[@]}

cat blank.txt > tmp.txt
for i in $(seq 1 ${replacelength})
do
    echo Replacing ${file[i]} ...
    sed -e "/${replace[i]}/r ${file[i]}" -e "/${replace[i]}/d" tmp.txt > tmp_2.txt
    mv tmp_2.txt tmp.txt
done
mv tmp.txt file.txt

如果你不害怕.zip文件,你可以尝试这个例子,只要它在线:http://ablage.stabentheiner.de/2013-04-16_contentreplace.zip

答案 6 :(得分:1)

我会使用perl替换为-i.ext选项

perl -pi.bak -e 's|INSERT_HERE1|`cat FILE1`|ge; 
                 s|INSERT_HERE2|`cat FILE2`|ge;' myfile

然后,使用diff myfile.bak myfile验证: