【发布时间】:2017-04-17 01:40:36
【问题描述】:
我有以下文件:
table.txt(逗号分隔)
1,Example Title
COL1,COL2,COL3,COL4,COL5
BRCC,ACGC,15869,105A,1
BCAS,GAAG,73345,369T,2
模板.awk
function parse_print(s){
s = gensub(/^\s+|\s+$/,"","g",s)
s = gensub(/[\42]/,"\\\\\042","g",s)
s = gensub(/\$[0-9]+/,"\" & \"","g",s)
s = gensub(/\$e/,"\" & \"","g",s)
return s;
}
/^[^%]/{print "print \"" parse_print($0) "\""; next}
/^%BEGIN$|^%END$/{print substr($1,2) "{"; next}
/^%END.+$/{print "}"; next}
{print substr($1,2) "{"}
{
if($2 == "%FOREACH"){
pprint = gensub(/(\S+\s+){2}(.*)/,"\\2","g")
print "for(e=1; e<=NF; ++e) print \"" parse_print(pprint) "\""
}else{
pprint = gensub(/\S+\s+(.*)/,"\\1","g")
print "print \"" parse_print(pprint) "\""
}
}
{print "}"}
table.tawk
%BEGIN
<style>
.my_table {border-bottom:3px double black; border-collapse: collapse; }
.my_table tr.header{border-bottom:3px double black;}
.my_table td{text-align: center;}
</style>
<table class="my_table">
%ENDBEGIN
%NR==1 <caption>Table $1. $2</caption>
%NR==2 <tr class="header">
%NR>2 <tr>
%NR==2 %FOREACH <th>$e</th>
%NR>2 %FOREACH <td>$e</td>
%NR!=1 </tr>
%END
</table>
%ENDEND
元编程.sh
#!/bin/sh
# metaprogram
awk '@include "template"' $1 > .table.awk
awk -vFS="," -f .table.awk $2
rm .table.awk
这个想法是使用元编程来分离表示的逻辑,这是基于@kent 在How to format text in html using awk's question 中的注释,用于将文本文件转换为 html 表格格式。
./metaprogramming.sh table.tawk table.txt > table.html
这个得到,
<style>
.my_table {border-bottom:3px double black; border-collapse: collapse; }
.my_table tr.header{border-bottom:3px double black;}
.my_table td{text-align: center;}
</style>
<table class="my_table">
<caption>Table 1. Example Title</caption>
<tr class="header">
<th>COL1</th>
<th>COL2</th>
<th>COL3</th>
<th>COL4</th>
<th>COL5</th>
</tr>
<tr>
<td>BRCC</td>
<td>ACGC</td>
<td>15869</td>
<td>105A</td>
<td>1</td>
</tr>
<tr>
<td>BCAS</td>
<td>GAAG</td>
<td>73345</td>
<td>369T</td>
<td>2</td>
</tr>
</table>
问题 1
有没有办法在不创建临时文件.table.awk,甚至不使用bash 脚本(awk 直接调用)的情况下进行调用?
问题奖励
有没有办法更好地做到这一点? awk 中是否有图书馆已经这样做了?
【问题讨论】:
-
你总是可以做类似的事情(检查语法和引号!)
awk -vFS="," $(awk '@include "template"' $1) $2以避免需要临时文件。您所拥有的似乎是一种合理的方法,并且没有执行此 AFAIK 的 awk 库。你应该在命令之间抛出一个&&,以确保你只在前一个成功的情况下执行下一个。 -
@EdMorton 非常感谢,
awk -vFS="," "$(awk '@include "template"' table.tawk)" table.txt完成了这项工作,注意:引号是必需的
标签: bash awk metaprogramming