用文件的内容替换某些标记(使用 bash 脚本)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4379207/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Replace certain token with the content of a file (using a bash-script)
提问by aioobe
I have a file containing some text and the words INSERT_HERE1and INSERT_HERE2. I'd like to replace these words with the content of file1.txtand file2.txtrespectively.
我有一个包含一些文本和单词INSERT_HERE1和的文件INSERT_HERE2。我想要的内容替换这些词file1.txt和file2.txt分别。
I suspect sedor awkcould pull it off but I've basically never used them.
我怀疑sed或awk可以实现它,但我基本上从未使用过它们。
采纳答案by codaddict
If you are okay with Perl you can do:
如果你对 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`/e;print' file
foo
this is file1
bar
this is file2
baz
$
回答by MattoxBeckman
Sed does have a built-in read file command. The commands you want would look something like this:
Sed 确实有一个内置的读取文件命令。你想要的命令看起来像这样:
$ 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_HEREtags. 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 -fto run it.
r 命令读取文件,d 命令删除带有INSERT_HERE标签的行。您需要使用大括号,因为 sed 命令和多行输入,因为 sed 命令必须从它们自己的行开始,并且根据您的 shell,您可能需要\在行的末尾以避免过早执行。如果这是你sed -f经常使用的东西,你可以把命令放在一个文件中并用来运行它。
回答by Paused until further notice.
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.
您可能希望在这里和那里添加一些额外的换行符,具体取决于您希望输出的外观。
回答by SiegeX
Easily done with Bash. If you need it to be POSIX shell let me know:
使用 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
回答by Jonathan
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:
不过,我更推荐 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";
}
This assumes that INSERT_HERE1 and INSERT_HERE2 may only appear once per line, and that the file1.txtdoes not include the text INSERT_HERE2 (wouldn't be difficult to fix, though). Use like this:
这假设 INSERT_HERE1 和 INSERT_HERE2 每行只能出现一次,并且file1.txt不包括文本 INSERT_HERE2(虽然不难修复)。像这样使用:
./script <file >file.out
回答by dersimn
This snippet replaces any section that is specified in the upper array. For e.g. here
此代码段替换了上面数组中指定的任何部分。例如这里
<!--insert.txt-->
with the contents of "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
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
如果你不害怕 .zip 文件,只要它在线,你可以试试这个例子:http: //ablage.stabentheiner.de/2013-04-16_contentreplace.zip

