将某些标记替换为文件的内容(使用 bash 脚本)

发布于 2024-10-06 08:02:35 字数 185 浏览 3 评论 0原文

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

我怀疑 sed 或 awk 可以成功,但我基本上从未使用过它们。

I have a file containing some text and the words INSERT_HERE1 and INSERT_HERE2. I'd like to replace these words with the content of file1.txt and file2.txt respectively.

I suspect sed or awk could pull it off but I've basically never used them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

注定孤独终老 2024-10-13 08:02:35

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 命令和多行输入,您需要使用大括号,因为 sed 命令必须在自己的行上开始,并且根据您的 shell,您可能需要在行末尾使用 \ 来避免过早执行。如果这是您经常使用的东西,您可以将命令放入文件中并使用 sed -f 来运行它。

Sed does have a built-in read file command. The commands you want would look something like this:

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

This would output

foo
this is file1
bar
this is file2
baz

The r command reads the file, and the d command deletes the line with the INSERT_HERE tags. You need to use the curly braces since sed commands and multi-line input since sed commands have to start on their own line, and depending on your shell, you may need \ at the end of the lines to avoid premature execution. If this is something you would use a lot, you can just put the command in a file and use sed -f to run it.

转身以后 2024-10-13 08:02:35

如果你熟悉 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
$ 

If you are okay with Perl you can do:

$ 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
$ 
思念绕指尖 2024-10-13 08:02:35

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

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

This is not tested, but would be pretty close to what you need:

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

It will not properly handle a file with slashes in it, though, so you may need to tweak it a bit.

I'd recommend Perl instead, though. Something like this:

#!/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";
}

This assumes that INSERT_HERE1 and INSERT_HERE2 may only appear once per line, and that the file1.txt does not include the text INSERT_HERE2 (wouldn't be difficult to fix, though). Use like this:

./script <file >file.out
对风讲故事 2024-10-13 08:02:35

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

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

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

This is suitable for small substitution files that may be substituted many times:

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

You may want to add some extra newlines here and there, depending on how you want your output to look.

北方。的韩爷 2024-10-13 08:02:35

使用 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

Easily done with Bash. If you need it to be POSIX shell let me know:

#!/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
若相惜即相离 2024-10-13 08:02:35

此代码片段替换上面数组中指定的任何部分。例如,这里

<!--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

This snippet replaces any section that is specified in the upper array. For e.g. here

<!--insert.txt-->

with the contents of "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

If you're not afraid of .zip files you can try this example as long as it is online: http://ablage.stabentheiner.de/2013-04-16_contentreplace.zip

可遇━不可求 2024-10-13 08:02:35

我将使用 Perl 的就地替换 -i.ext 选项

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

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

I would use perl's in place replacement with -i.ext option

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

Then, use diff myfile.bak myfile to verify:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文