【发布时间】:2011-05-21 17:19:24
【问题描述】:
我有一个文件,其中包含一些文本和单词INSERT_HERE1 和INSERT_HERE2。我想分别用file1.txt和file2.txt的内容来替换这些词。
我怀疑sed 或awk 可以成功,但我基本上从未使用过它们。
【问题讨论】:
我有一个文件,其中包含一些文本和单词INSERT_HERE1 和INSERT_HERE2。我想分别用file1.txt和file2.txt的内容来替换这些词。
我怀疑sed 或awk 可以成功,但我基本上从未使用过它们。
【问题讨论】:
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 来运行它。
【讨论】:
如果你对 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
$
【讨论】:
这未经测试,但与您需要的非常接近:
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
【讨论】:
file1.txt包含'等字符。
sed 中做到这一点并允许输入文件包含任何字符。不幸的是,我不知道awk,所以我不能说那里是否有更好的解决方案。 sed 是标准而 perl 不是标准的,你在哪种系统上?
这适用于可能被多次替换的小替换文件:
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
您可能希望在这里和那里添加一些额外的换行符,具体取决于您希望输出的外观。
【讨论】:
awk -v "f1=$(< file1)" -v "f2=$(< file2)" '{gsub(...
使用 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
【讨论】:
这个 sn-p 替换了上面数组中指定的任何部分。例如这里
<!--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
【讨论】:
我会用-i.ext 选项替换perl
perl -pi.bak -e 's|INSERT_HERE1|`cat FILE1`|ge;
s|INSERT_HERE2|`cat FILE2`|ge;' myfile
然后,使用diff myfile.bak myfile进行验证:
【讨论】: