awk中递归读取文件的方法
How to read files recursively in awk
我有一堆乳胶文件 使用 \input{filename.tex}
宏(它的工作方式类似于 C 中的 #include
),并且我想解决它们,这样我就可以将它们全部输出到一个 .tex 文件(该文件必须粘贴在 \input{}
宏的位置,这是安全的假设每个文件只被引用一次)。
示例:
tesis.tex:
My thesis.
\input{chapter1.tex}
More things
\input{chapter2.tex}
chapter1.tex:
Chapter 1 content.
chapter2.tex:
Chapter 2 content.
\include{section2-2.tex}
section2-2.tex:
Section 1.
期望的结果应该是:
My thesis.
Chapter 1 content.
More things
Chapter 2 content.
Section 1.
如果只有 \input{foo.tex}
关卡,我可以用这个 AWK 程序解决这个问题:
/\input\{.*\}/{
sub(/^[^{]*{/,"",[=15=])
sub(/}[^}]*$/,"",[=15=])
system("cat " [=15=])
next
}
{
print [=15=]
}
有什么方法可以在 AWK 中递归读取文件吗?
(我愿意用任何其他语言来做,但是 posix 最好)
谢谢!
因为你也标记了它 bash,类似这样的东西可以在 bash 中工作,但它没有经过测试:
#!/bin/bash
function texextract {
while read -r line;do
if [[ "$line" =~ "input" || "$line" =~ "include" ]];then #regex may need finetune
filename="${line: 0:-1}" #removes the last } from \include{section2-2.tex}
filename="${filename##*{}" #removes from start up to { ---> filename=section2-2.tex
texextract "$filename" #call itself with new args
else
echo "$line" >>commonbigfile
fi
done <"" # holds the filename send by caller
return
}
texextract tesis.tex #masterfile
在 bash 4.4(可能还有其他版本)中,函数可以调用自身。这就是我在这里使用的。
这是 awk 中的一个解决方案,在作业的递归函数中使用 getline
。我假设 chapter2.tex
:
Chapter 2 content.
\input{section2-2.tex}
代码:
$ cat program.awk
function recurse(file) { # the recursive function definition
while((getline line<file) >0) { # read parameter given file line by line
if(line~/^\input/) { # if line starts with \input
gsub(/^.*{|}.*$/,"",line) # read the filename from inside {}
# print "FILE: " line # debug
recurse(line) # make the recursive function call
}
else print line # print records without \input
}
close(file) # after file processed close it
}
{ # main program used to just call recurse()
recurse(FILENAME) # called
exit # once called, exit
}
运行它:
$ awk -f program.awk tesis.tex
My thesis.
Chapter 1 content.
More things
Chapter 2 content.
Section 1.
解决方案预计 \input
位于记录的开头,上面没有任何其他数据。
我有一堆乳胶文件 使用 \input{filename.tex}
宏(它的工作方式类似于 C 中的 #include
),并且我想解决它们,这样我就可以将它们全部输出到一个 .tex 文件(该文件必须粘贴在 \input{}
宏的位置,这是安全的假设每个文件只被引用一次)。
示例:
tesis.tex:
My thesis.
\input{chapter1.tex}
More things
\input{chapter2.tex}
chapter1.tex:
Chapter 1 content.
chapter2.tex:
Chapter 2 content.
\include{section2-2.tex}
section2-2.tex:
Section 1.
期望的结果应该是:
My thesis.
Chapter 1 content.
More things
Chapter 2 content.
Section 1.
如果只有 \input{foo.tex}
关卡,我可以用这个 AWK 程序解决这个问题:
/\input\{.*\}/{
sub(/^[^{]*{/,"",[=15=])
sub(/}[^}]*$/,"",[=15=])
system("cat " [=15=])
next
}
{
print [=15=]
}
有什么方法可以在 AWK 中递归读取文件吗?
(我愿意用任何其他语言来做,但是 posix 最好)
谢谢!
因为你也标记了它 bash,类似这样的东西可以在 bash 中工作,但它没有经过测试:
#!/bin/bash
function texextract {
while read -r line;do
if [[ "$line" =~ "input" || "$line" =~ "include" ]];then #regex may need finetune
filename="${line: 0:-1}" #removes the last } from \include{section2-2.tex}
filename="${filename##*{}" #removes from start up to { ---> filename=section2-2.tex
texextract "$filename" #call itself with new args
else
echo "$line" >>commonbigfile
fi
done <"" # holds the filename send by caller
return
}
texextract tesis.tex #masterfile
在 bash 4.4(可能还有其他版本)中,函数可以调用自身。这就是我在这里使用的。
这是 awk 中的一个解决方案,在作业的递归函数中使用 getline
。我假设 chapter2.tex
:
Chapter 2 content.
\input{section2-2.tex}
代码:
$ cat program.awk
function recurse(file) { # the recursive function definition
while((getline line<file) >0) { # read parameter given file line by line
if(line~/^\input/) { # if line starts with \input
gsub(/^.*{|}.*$/,"",line) # read the filename from inside {}
# print "FILE: " line # debug
recurse(line) # make the recursive function call
}
else print line # print records without \input
}
close(file) # after file processed close it
}
{ # main program used to just call recurse()
recurse(FILENAME) # called
exit # once called, exit
}
运行它:
$ awk -f program.awk tesis.tex
My thesis.
Chapter 1 content.
More things
Chapter 2 content.
Section 1.
解决方案预计 \input
位于记录的开头,上面没有任何其他数据。