自动将指定文件插入另一个文件(使用sed、AWK或Perl)
假设我有一个文件,自动将指定文件插入另一个文件(使用sed、AWK或Perl),perl,bash,sed,awk,Perl,Bash,Sed,Awk,假设我有一个文件,Foo.in: Contents of Foo 和Bar.in INSERT Foo.in Contents of Bar 我想编写一个sed脚本,用xyz文件的实际内容替换INSERT xyz。在这个特定的示例中,我希望生成包含以下内容的Bar.out文件: Contents of Foo Contents of Bar 我曾考虑使用演示过的sed的r命令,但问题是要插入的文件名是在文件本身中指定的。我考虑过扫描文件中的INSERT命令,然后对找到的每个INSERT分别
Foo.in
:
Contents of Foo
和Bar.in
INSERT Foo.in
Contents of Bar
我想编写一个sed
脚本,用xyz
文件的实际内容替换INSERT xyz
。在这个特定的示例中,我希望生成包含以下内容的Bar.out
文件:
Contents of Foo
Contents of Bar
我曾考虑使用演示过的sed
的r
命令,但问题是要插入的文件名是在文件本身中指定的。我考虑过扫描文件中的INSERT
命令,然后对找到的每个INSERT
分别运行sed
,但这是一个非常糟糕的解决方案,复杂性为O(n^2)。我更愿意使用sed或AWK来实现这一点,但如果其他方法都失败了,则可以使用Perl脚本。$cat Foo.in
$ cat Foo.in
Contents of Foo
$ cat Bar.in
INSERT Foo.in
Contents of Bar.in
$ awk '/INSERT/{while((getline line < $2) > 0 ){print line}close($2);next}1' Bar.in
Contents of Foo
Contents of Bar.in
食物内容
$cat Bar.in
插入Foo.in
酒吧的内容
$awk'/INSERT/{while((getline<$2)>0){print line}close($2);next}1'Bar.in
食物内容
酒吧的内容
这很容易做到。下面是一个小的Perl脚本:
#/usr/bin/env perl
严格使用;
使用警告;
使用自动模具;
while(){
#如果此行是INSERT命令,则捕获文件名并将其插入
如果(我的($filename)=/^INSERT\s+(.+)$/){
使用正则表达式打开我的$fh,“Amon
perl -MFile::Slurp -pe '$_= read_file($1) if /^INSERT\s+(.+)$/' file
您也可以在不加载Perl模块的情况下使用更少的字符执行此操作:
perl -pe 'open $F,"<$1" and $_=<$F> if /^INSERT\s+(.+)$/' [file]
perl-pe'open$F,“递归
AWK代码:
awk '
function fetch(inp){
while( (getline p < inp) > 0)
print p
close(inp)
}
/INSERT/{
while((getline line < $2) > 0)
{
if(line ~ /INSERT/){
split(line,A)
fetch(A[2])
next
}
else{
print
}
}
close($2)
next
}1
' Bar.in
---编辑---
$ cat test.awk
function fetch(inp){
while( (getline p < inp) > 0)
print p
close(inp)
}
/INSERT/{
while((getline line < $2) > 0)
{
if(line ~ /INSERT/){
split(line,A)
fetch(A[2])
next
}
else{
print
}
}
close($2)
next
}1
我认为是O(n)。但更重要的是,除非你有数千个文件,并且每隔一天就需要这样做,否则为什么要关心渐进的复杂性。如果问题真的是由资源决定的,那么两种脚本语言都不是正确的答案。编辑:等等,这是关于只对一个文件这样做吗?那么复杂性完全没有意义…我有很多文件如果我扫描每个文件N次(其中N是插入杂注的数量),那么复杂性是O(N^2),而不是O(N)。我同意这不是一个大问题,但这表明设计不好。正如您所提到的,如果要插入的内容是sed脚本中用作引用的值,则sed不会替换动态内容。文件名是“硬编码”的。现在您可以动态创建一个sed脚本,但在本例中,如果n是pragma的数量,则awk要好得多。对不起,在脚本的世界中,我会在脑海中保留一句话:“Perl脚本是“正确的”“如果你开始考虑运行时效率和资源管理,Perl可能是一种错误的语言,对于sed和awk来说,这很可能是正确的。有可能让这个解决方案递归地工作吗?@Jan Stolarek我刚刚在另一篇文章中发了帖子,请看一看……嗯……看起来我对我来说不起作用。我也试着把它放到一个文件中,并用-f
选项运行awk
,但运气不好。像这样试试awk-f test.awk吧。在中,我试过了。它似乎不起作用:-/在编辑中检查测试文件的内容,看起来你删除了。在中,顺便问一下,有什么错误或者消息?没有错误消息-没有任何东西被替换。当我用原始的、非递归的版本替换递归版本时,一切都很好。
INSERT Foo.in
1
2
3
4
5
Contents of Bar.in
$ cat test.awk
function fetch(inp){
while( (getline p < inp) > 0)
print p
close(inp)
}
/INSERT/{
while((getline line < $2) > 0)
{
if(line ~ /INSERT/){
split(line,A)
fetch(A[2])
next
}
else{
print
}
}
close($2)
next
}1
$ awk -f test.awk Bar.in