避免在awk中打印两次最后一行
问题描述:
我想将一个JSON格式的文件放入一列,这样做我认为awk可以是一个很棒的工具。我的输入是(例如):避免在awk中打印两次最后一行
a
b
c
d
e
而且我的输出,我想的是:
{nodes:[{id='a'},
{id='b'},
{id='c'},
{id='d'},
{id='e'}]}
我想有两个不同的代码。第一个是:
BEGIN{
FS = "\t"
printf "{nodes:["
}
{printf "{'id':'%s'},\n",$1}
END{printf "{'id':'%s'}]}\n",$1}
但是我打印两次的最后一行:
{nodes:[{id='a'},
{id='b'},
{id='c'},
{id='d'},
{id='e'},
{id='e'}]}
,我尝试的另一种选择是用函数getline:
BEGIN{
FS = "\t"
printf "{nodes:["
}
{printf getline==0 ? "{'id':'%s'}]}" : "{'id':'%s'},\n",$1}
但出于某种原因,函数getline在最后一行总是1,而不是0,所以:
{nodes:[{id='a'},
{id='b'},
{id='c'},
{id='d'},
{id='e'},
有没有解决我的问题的建议?
答
在awk中。 outputing之前缓冲输出变量b
并对其进行处理:
$ awk 'BEGIN{b="{nodes:["}{b=b "{id=\x27" $0 "\x27},\n"}END{sub(/,\n$/,"]}",b);print b}' file
{nodes:[{id='a'},
{id='b'},
{id='c'},
{id='d'},
{id='e'}]}
解释:
BEGIN { b="{nodes:[" } # front matter
{ b=b "{id=\x27" $0 "\x27},\n" } # middle
END { sub(/,\n$/,"]}",b); print b } # end matter and replace ,\n in the end
# with something more appropriate
+0
我不明白你为什么把\ x27 – oscarcapote
+1
尝试用'''替换它们。“https://www.gnu.org/软件/ GAWK /手动/ html_node/Quoting.html –
答
解决方案(感谢@Ruud和@suleiman)
BEGIN{
FS = "\t"
printf "{'nodes':["
}
NR > 1{printf "{'id':'%s'},\n",prev}
{prev = $1}
END{printf "{'id':'%s'}]}",prev}
答
试试这个 -
$awk -v count=$(wc -l < f) 'BEGIN{kk=getline;printf "{nodes:[={'id':'%s'},\n",$kk}
> {
> if(NR < count)
> {
> {printf "{'id':'%s'},\n",$1}
> }}
> END{printf "{'id':'%s'}]}\n",$1}' f
{nodes:[={id:a},
{id:b},
{id:c},
{id:d},
{id:e}]}
这可能会帮助:http://stackoverflow.com/questions/11866860/how-do-you-skip -the-last-line-w-awk –
你不使用valide json格式。除了数字和布尔值之外,每个名称和值都需要用引号'''包围,你应该使用工具'jq'来验证你的json数据,它必须是'awk',还是可以创建一个简单的'回声'与它的所有东西? – suleiman
都有理由,现在我的代码工作 – oscarcapote