给出类似于以下文件的内容:
文件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?
答案 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