在gawk动作中添加输入文件

时间:2014-12-10 13:38:02

标签: awk gawk

给出类似于以下文件的内容:

文件A:

module modA;
include file B;
include file C;
[more stuff]
end module;

文件B:

value x=5;
value y=7;
include file D;
[etc.]

文件C:

value z=10;
value title="A string";
[etc.]

文件D:

value x1=15;
[etc.]

我希望能够使用gawk来捕获include file行,打印出来,然后让gawk读取找到的新文件,或者至少添加它就像在命令行上一样到文件列表。输出看起来像这样:

A: B
A: C
A: D

我的问题是:如何在不知道先验需要的情况下让gawk读取文件B,C和D?

2 个答案:

答案 0 :(得分:5)

假设file的每一行都是文件名,这将对名称包含在do stuff中的每个文件执行file

awk 'NR==FNR{ ARGV[ARGC] = $0; ARGC++; next } { do stuff }' file

如果您不希望编辑问题以更好地描述您的要求(并且丢失所有特定于域的术语,例如specialty dependency generator for Motif UIL files,那只会混淆您的问题,那么这一切都只是我们其余人的记录和字段或行和列),并提供特定的样本输入和预期输出。

鉴于您更新的问题,请参阅我在http://awk.info/?tip/getline给出递归下降解析的示例:

 awk 'function read(file) { 
        while ( (getline < file) > 0) { 
            if ($1 == "include") { 
                 read($2) 
            } else { 
                 print > ARGV[2] 
            } 
        } 
        close(file) 
  } 
  BEGIN{ 
     read(ARGV[1]) 
     ARGV[1]="" 
     close(ARGV[2]) 
 }1' file1 tmp 

以上不仅扩展了说&#34;包含子文件&#34;的所有行,而是通过将结果写入tmp文件,重置ARGV [1](最高级别输入文件)而不重置ARGV [ 2](tmp文件),然后让awk对扩展结果进行任何正常的记录解析,因为它现在存储在tmp文件中。如果您不需要,只需执行&#34; print&#34; to stdout并删除对tmp文件或ARGV的任何其他引用[2]。在这种情况下,由于使用$ 1和$ 2很方便,并且程序的其他部分没有引用任何内置变量,因此使用了getline而没有填充显式变量。此方法的递归深度限制为OS一次允许的打开文件总数。

如果您无法弄清楚如何调整以满足您的需求,请告诉我们。

答案 1 :(得分:1)

好的,好吧,这不是awk但是我无法抗拒:

#!/usr/bin/perl -0
$_=<>;    
while( s/include\s+(\S+);/`cat $1`/e){ }
print