我正在尝试使用 awk 来做一些简单的模板。我有一个“模板”文件,如下所示:
{
"Thing": {
"Code": [
#include_code
]
}
}
我使用下面的 awk 程序将该#include_code
行替换为文件的内容,但每行都用双引号括起来并以逗号结尾(以在输出中生成有效的 JSON 列表)。
#!/usr/bin/awk -f
! /#include_code/ { print $0 }
/#include_code/ {
while(( getline line<"test_file.js") > 0 ) {
print "\"" line "\","
}
}
哪里test_file.js
:
index.handler = (event, context) => {
return true;
}
我的问题是我不想打印最后一个逗号,但我不确定如何防止打印该逗号。明确地说,这是输出:
{
"Thing": {
"Code": [
"index.handler = (event, context) => {",
" return true;",
"}", <--- I don't want this comma...
]
}
}
虽然我想要一个使用 awk 执行此操作的答案(因为我正在尝试学习它)。我会很高兴得到一个答案,它向我指出了您建议我使用的不同的模板工具。
答案1
一种方法是计算脚本开头的行数。输出时,只有当你的行号与行数不匹配时,才在末尾输出一个逗号。解释了如何执行此操作这里。
另一种方法是,在输出第一个条目时不打印逗号,而是打印一个前随后的条目。这可以按如下方式完成:
awk -F, '{if (!i)printf "\""$0"\"";else printf ",\n\""$0"\"";i=1}END{print ""}' a.in
这绝对干净得多。
还有第三种方法。代码
if(getline == 0)
读取下一行,从而告诉您是否位于文件末尾。这样做比上面的方法更干净,但是会因有效读取文件两次而产生开销,因此除非第二种方法失败,否则我不会使用它(例如,我也必须以不同的方式处理倒数第二行) 。
答案2
这样做可能更容易:
sed 's/.*/"&"/;$!s/$/,/' test_file.js | sed '/#include_code/{
r /dev/stdin
d;}' template
(假设 只出现一次#include_code
)。
使用awk
,您可以这样做:
awk '
/#include_code/ {
sep = ""
while((getline < "test_file.js") > 0) {
printf "%s", sep "\"" $0 "\""
sep = ",\n"
}
if (sep) print ""
next
}
{print}' template
您还可以使用与sed
上面类似的方法:
CODE='test_file.js' SED='sed '\''s/.*/"&"/;$!s/$/,/'\' "$CODE"' awk '
/#include_code/{system(ENVIRON["SED"); next};{print}' template