awk 中的元编程,将文件转换为 html table 格式
Metaprogramming in awk, convert file to html table format
我有以下文件:
table.txt (comma separate)
1,Example Title
COL1,COL2,COL3,COL4,COL5
BRCC,ACGC,15869,105A,1
BCAS,GAAG,73345,369T,2
template.awk
function parse_print(s){
s = gensub(/^\s+|\s+$/,"","g",s)
s = gensub(/[]/,"\\2","g",s)
s = gensub(/$[0-9]+/,"\" & \"","g",s)
s = gensub(/$e/,"\" & \"","g",s)
return s;
}
/^[^%]/{print "print \"" parse_print([=13=]) "\""; next}
/^%BEGIN$|^%END$/{print substr(,2) "{"; next}
/^%END.+$/{print "}"; next}
{print substr(,2) "{"}
{
if( == "%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 . </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
metaprogramming.sh
#!/bin/sh
# metaprogram
awk '@include "template"' > .table.awk
awk -vFS="," -f .table.awk
rm .table.awk
想法是使用元编程来分离表示的逻辑,这基于@kent 在 中的评论,用于将文本文件转换为html table 格式。
./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>
问题一
有没有办法在不创建临时文件 .table.awk
甚至不使用 bash
脚本(awk
直接调用)的情况下进行调用?
问题奖金
有没有办法做得更好? awk
中是否有图书馆已经这样做了?
TXR 是一种工具,它提供了一种用于基于模板的数据提取和格式化的语言,并结合了原始的 Lisp 方言:
在format.txr
中我们有:
@num,@title
@(coll)@{heading /[^,]+/}@(end)
@(collect)
@ (coll)@{data /[^,]+/}@(end)
@(end)
@(output :filter :tohtml)
<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 @num. @title</caption>
<tr class="header">
@ (repeat)
<th>@heading</th>
@ (end)
</tr>
@ (repeat)
<tr>
@ (repeat)
<td>@data</td>
@ (end)
</tr>
@ (end)
</table>
@(end)
我们像这样将它应用于 data
文件:
$ txr format.txr data
<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>
请注意 :filter :tohtml
负责 HTML 的转义字符;例如,如果数据包含 &
,我们会得到 &
等等。
垂直collect
和水平coll
指令隐含地将匹配的模式变量支持到嵌套列表中; repeat
隐式展开列表,因此只有像 @data
这样的简单变量引用出现在输入匹配部分和输出中。
下面是Vim下语法高亮的样子,很清楚什么是模板material,什么是TXR语法:
我有以下文件:
table.txt (comma separate)
1,Example Title
COL1,COL2,COL3,COL4,COL5
BRCC,ACGC,15869,105A,1
BCAS,GAAG,73345,369T,2
template.awk
function parse_print(s){
s = gensub(/^\s+|\s+$/,"","g",s)
s = gensub(/[]/,"\\2","g",s)
s = gensub(/$[0-9]+/,"\" & \"","g",s)
s = gensub(/$e/,"\" & \"","g",s)
return s;
}
/^[^%]/{print "print \"" parse_print([=13=]) "\""; next}
/^%BEGIN$|^%END$/{print substr(,2) "{"; next}
/^%END.+$/{print "}"; next}
{print substr(,2) "{"}
{
if( == "%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 . </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
metaprogramming.sh
#!/bin/sh
# metaprogram
awk '@include "template"' > .table.awk
awk -vFS="," -f .table.awk
rm .table.awk
想法是使用元编程来分离表示的逻辑,这基于@kent 在
./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>
问题一
有没有办法在不创建临时文件 .table.awk
甚至不使用 bash
脚本(awk
直接调用)的情况下进行调用?
问题奖金
有没有办法做得更好? awk
中是否有图书馆已经这样做了?
TXR 是一种工具,它提供了一种用于基于模板的数据提取和格式化的语言,并结合了原始的 Lisp 方言:
在format.txr
中我们有:
@num,@title
@(coll)@{heading /[^,]+/}@(end)
@(collect)
@ (coll)@{data /[^,]+/}@(end)
@(end)
@(output :filter :tohtml)
<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 @num. @title</caption>
<tr class="header">
@ (repeat)
<th>@heading</th>
@ (end)
</tr>
@ (repeat)
<tr>
@ (repeat)
<td>@data</td>
@ (end)
</tr>
@ (end)
</table>
@(end)
我们像这样将它应用于 data
文件:
$ txr format.txr data
<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>
请注意 :filter :tohtml
负责 HTML 的转义字符;例如,如果数据包含 &
,我们会得到 &
等等。
垂直collect
和水平coll
指令隐含地将匹配的模式变量支持到嵌套列表中; repeat
隐式展开列表,因此只有像 @data
这样的简单变量引用出现在输入匹配部分和输出中。
下面是Vim下语法高亮的样子,很清楚什么是模板material,什么是TXR语法: