避免在awk中打​​印最后一行两次

时间:2017-04-04 09:46:44

标签: json bash awk

我试图将JSON格式放到一个包含一列的文件中,为此我认为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'},

有什么建议可以解决我的问题吗?

3 个答案:

答案 0 :(得分:1)

在awk中。将输出缓冲到变量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

答案 1 :(得分:0)

解决方案(感谢@Ruud和@suleiman)

127.0.0.1 hello_world
::1 hello_world

答案 2 :(得分:0)

试试这个 -

$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}]}