I have the following records:
我有以下记录:
31 Stockholm
42 Talin
34 Helsinki
24 Moscow
15 Tokyo
And I want to convert it to JSON with AWK. Using this code:
我想用AWK将它转换为JSON。使用此代码:
#!/usr/bin/awk
BEGIN {
print "{";
FS=" ";
ORS=",\n";
OFS=":";
};
{
if ( !a[city]++ && NR > 1 ) {
key = $2;
value = $1;
print "\"" key "\"", value;
}
};
END {
ORS="\n";
OFS=" ";
print "\b\b}";
};
Gives me this:
给我这个:
{
"Stockholm":31,
"Talin":42,
"Helsinki":34,
"Moscow":24,
"Tokyo":15, <--- I don't want this comma
}
The problem is that trailing comma on the last data line. It makes the JSON output not acceptable. How can I get this output:
问题是在最后一条数据行上尾随逗号。它使JSON输出不可接受。我怎样才能得到这个输出:
{
"Stockholm":31,
"Talin":42,
"Helsinki":34,
"Moscow":24,
"Tokyo":15
}
4 个解决方案
#1
9
Mind some feedback on your posted script?
请注意您发布的脚本的一些反馈?
#!/usr/bin/awk # Just be aware that on Solaris this will be old, broken awk which you must never use
BEGIN {
print "{"; # On this and every other line, the trailing semi-colon is a pointless null-statement, remove all of these.
FS=" "; # This is setting FS to the value it already has so remove it.
ORS=",\n";
OFS=":";
};
{
if ( !a[city]++ && NR > 1 ) { # awk consists of <condition>{<action} segments so move this condition out to the condition part
# also, you never populate a variable named "city" so `!a[city]++` won't behave sensibly.
key = $2;
value = $1;
print "\"" key "\"", value;
}
};
END {
ORS="\n"; # no need to set ORS and OFS when the script will no longer use them.
OFS=" ";
print "\b\b}"; # why would you want to print a backspace???
};
so your original script should have been written as:
所以你的原始剧本应该写成:
#!/usr/bin/awk
BEGIN {
print "{"
ORS=",\n"
OFS=":"
}
!a[city]++ && (NR > 1) {
key = $2
value = $1
print "\"" key "\"", value
}
END {
print "}"
}
Here's how I'd really write a script to convert your posted input to your posted output though:
这是我如何写一个脚本来将你发布的输入转换为你发布的输出:
$ cat file
31 Stockholm
42 Talin
34 Helsinki
24 Moscow
15 Tokyo
$
$ awk 'BEGIN{print "{"} {printf "%s\"%s\":%s",sep,$2,$1; sep=",\n"} END{print "\n}"}' file
{
"Stockholm":31,
"Talin":42,
"Helsinki":34,
"Moscow":24,
"Tokyo":15
}
#2
2
You have a couple of choices. An easy one would be to add the comma of the previous line as you are about to write out a new line:
你有几个选择。当您要写出新行时,一个简单的方法是添加上一行的逗号:
-
Set a variable
first = 1
in yourBEGIN
.在BEGIN中设置变量first = 1。
-
When about to print a line, check
first
. If it is1
, then just set it to0
. If it is0
print out a comma and a newline:当要打印一行时,请先检查。如果为1,则将其设置为0.如果为0,则打印出逗号和换行符:
if (first) { first = 0; } else { print ","; }
The point of this is to avoid putting an extra comma at the start of the list.
这一点是为了避免在列表的开头添加额外的逗号。
-
Use
printf("%s", ...)
instead ofprint ...
so that you can avoid the newline when printing a record.使用printf(“%s”,...)代替打印...这样可以在打印记录时避免换行。
-
Add an extra newline before the close brace, as in:
print "\n}";
在闭括号前添加一个额外的换行符,如:print“\ n}”;
Also, note that if you don't care about the aesthetics, JSON doesn't really require newlines between items, etc. You could just output one big line for the whole enchilada.
另外,请注意,如果你不关心美学,JSON并不需要项目之间的换行等。你可以为整个辣酱玉米饼馅输出一个大线。
#3
1
You should really use a json parser but here is how with awk
:
你应该真的使用json解析器,但这是如何使用awk:
BEGIN {
print "{"
}
NR==1{
s= "\""$2"\":"$1
next
}
{
s=s",\n\""$2"\":"$1
}
END {
printf "%s\n%s",s,"}"
}
Outputs:
{
"Stockholm":31,
"Talin":42,
"Helsinki":34,
"Moscow":24,
"Tokyo":15
}
#4
0
Why not use json
parser? Don't force awk
to do something isn't wasn't designed to do. Here is a solution using python
:
为什么不使用json解析器?不要强迫awk做某事不是不是设计做的。这是一个使用python的解决方案:
import json
d = {}
with open("file") as f:
for line in f:
(val, key) = line.split()
d[key] = int(val)
print json.dumps(d,indent=0)
This outputs:
{
"Helsinki": 34,
"Moscow": 24,
"Stockholm": 31,
"Talin": 42,
"Tokyo": 15
}
#1
9
Mind some feedback on your posted script?
请注意您发布的脚本的一些反馈?
#!/usr/bin/awk # Just be aware that on Solaris this will be old, broken awk which you must never use
BEGIN {
print "{"; # On this and every other line, the trailing semi-colon is a pointless null-statement, remove all of these.
FS=" "; # This is setting FS to the value it already has so remove it.
ORS=",\n";
OFS=":";
};
{
if ( !a[city]++ && NR > 1 ) { # awk consists of <condition>{<action} segments so move this condition out to the condition part
# also, you never populate a variable named "city" so `!a[city]++` won't behave sensibly.
key = $2;
value = $1;
print "\"" key "\"", value;
}
};
END {
ORS="\n"; # no need to set ORS and OFS when the script will no longer use them.
OFS=" ";
print "\b\b}"; # why would you want to print a backspace???
};
so your original script should have been written as:
所以你的原始剧本应该写成:
#!/usr/bin/awk
BEGIN {
print "{"
ORS=",\n"
OFS=":"
}
!a[city]++ && (NR > 1) {
key = $2
value = $1
print "\"" key "\"", value
}
END {
print "}"
}
Here's how I'd really write a script to convert your posted input to your posted output though:
这是我如何写一个脚本来将你发布的输入转换为你发布的输出:
$ cat file
31 Stockholm
42 Talin
34 Helsinki
24 Moscow
15 Tokyo
$
$ awk 'BEGIN{print "{"} {printf "%s\"%s\":%s",sep,$2,$1; sep=",\n"} END{print "\n}"}' file
{
"Stockholm":31,
"Talin":42,
"Helsinki":34,
"Moscow":24,
"Tokyo":15
}
#2
2
You have a couple of choices. An easy one would be to add the comma of the previous line as you are about to write out a new line:
你有几个选择。当您要写出新行时,一个简单的方法是添加上一行的逗号:
-
Set a variable
first = 1
in yourBEGIN
.在BEGIN中设置变量first = 1。
-
When about to print a line, check
first
. If it is1
, then just set it to0
. If it is0
print out a comma and a newline:当要打印一行时,请先检查。如果为1,则将其设置为0.如果为0,则打印出逗号和换行符:
if (first) { first = 0; } else { print ","; }
The point of this is to avoid putting an extra comma at the start of the list.
这一点是为了避免在列表的开头添加额外的逗号。
-
Use
printf("%s", ...)
instead ofprint ...
so that you can avoid the newline when printing a record.使用printf(“%s”,...)代替打印...这样可以在打印记录时避免换行。
-
Add an extra newline before the close brace, as in:
print "\n}";
在闭括号前添加一个额外的换行符,如:print“\ n}”;
Also, note that if you don't care about the aesthetics, JSON doesn't really require newlines between items, etc. You could just output one big line for the whole enchilada.
另外,请注意,如果你不关心美学,JSON并不需要项目之间的换行等。你可以为整个辣酱玉米饼馅输出一个大线。
#3
1
You should really use a json parser but here is how with awk
:
你应该真的使用json解析器,但这是如何使用awk:
BEGIN {
print "{"
}
NR==1{
s= "\""$2"\":"$1
next
}
{
s=s",\n\""$2"\":"$1
}
END {
printf "%s\n%s",s,"}"
}
Outputs:
{
"Stockholm":31,
"Talin":42,
"Helsinki":34,
"Moscow":24,
"Tokyo":15
}
#4
0
Why not use json
parser? Don't force awk
to do something isn't wasn't designed to do. Here is a solution using python
:
为什么不使用json解析器?不要强迫awk做某事不是不是设计做的。这是一个使用python的解决方案:
import json
d = {}
with open("file") as f:
for line in f:
(val, key) = line.split()
d[key] = int(val)
print json.dumps(d,indent=0)
This outputs:
{
"Helsinki": 34,
"Moscow": 24,
"Stockholm": 31,
"Talin": 42,
"Tokyo": 15
}