我需要将简单的txt列表转换为特定的json格式。
我的列表如下:
server1
server2
server3
server4
我需要具有如下所示的JSON输出:
{ "data": [
{ "{SERVER}":"server1" },
{ "{SERVER}":"server2" },
{ "{SERVER}":"server3" },
{ "{SERVER}":"server4" }
]}
我能够使用bash脚本生成此脚本,但是我不知道如何删除最后一行的逗号。该列表是动态的,并且每次运行脚本时可以具有不同数量的服务器。 有提示吗?
编辑:我当前的代码:
echo "{ "data": [" > /tmp/json_output
for srv in `cat /tmp/list`; do
echo "{ \"{SERVER}\":\"$srv\" }," >> /tmp/json_output
done
echo "]}" >> /tmp/json_output
我对此很陌生,如果我听起来有点笨拙,那就对不起。
答案 0 :(得分:0)
我会为此使用jq
。
$ jq -nR 'reduce inputs as $i ([]; .+[$i]) | map ({"{SERVER}": .}) | {data: .}' tmp.txt
{
"data": [
{
"{SERVER}": "server1"
},
{
"{SERVER}": "server2"
},
{
"{SERVER}": "server3"
},
{
"{SERVER}": "server4"
}
]
}
(在我看来,应该有一种更简单的方法来生成数组["server1", "server2", "server3", "server4"]
并馈送到map
过滤器中,但这是有效的。)
首先,我们首先创建一个由服务器名称组成的数组。
$ jq -nR 'reduce inputs as $item ([]; .+[$item])' tmp.txt
[
"server1",
"server2",
"server3",
"server4"
]
此数组被馈送到map
过滤器,该过滤器使用{SERVER}
键创建对象数组:
$ jq -nR 'reduce inputs as $item ([]; .+[$item]) | map ({"{SERVER}": .})' tmp.txt
[
{
"{SERVER}": "server1"
},
{
"{SERVER}": "server2"
},
{
"{SERVER}": "server3"
},
{
"{SERVER}": "server4"
}
]
最后,它用于创建一个将键data
映射到对象数组的对象,如顶部所示。
答案 1 :(得分:0)
正如其他人所说,最好使用jq
之类的工具。
另外,您可以使用数组并确定要处理的元素是否为最后一个元素,例如您的代码可以是:
declare -a servers
servers=($(cat /tmp/list))
pos=$(( ${#servers[*]} - 1 ))
last=${servers[$pos]}
echo "{ "data": [" > /tmp/json_output
for srv in "${servers[@]}"; do
if [[ $srv == $last ]]
then
echo "{ \"{SERVER}\":\"$srv\" }" >> /tmp/json_output
else
echo "{ \"{SERVER}\":\"$srv\" }," >> /tmp/json_output
fi
done
echo "]}" >> /tmp/json_output
答案 2 :(得分:0)
您可以使用Python 3进行此操作:
#!/usr/local/bin/python3
import os
import json
d = []
with open('listofservers.txt', 'r', encoding='utf-8') as f:
for server in f:
d.append({'{Server}' : server.rstrip("\n")})
print(json.dumps({'data': d}, indent=" "))
将打印:
{
"data": [
{
"{Server}": "server1"
},
{
"{Server}": "server2"
},
{
"{Server}": "server3"
},
{
"{Server}": "server4"
}
]
}
答案 3 :(得分:0)
这对于Xidel非常简单:
require 'serverspec'
require 'net/ssh'
set :backend, :ssh
if ENV['ASK_SUDO_PASSWORD']
begin
require 'highline/import'
rescue LoadError
fail "highline is not available. Try installing it."
end
set :sudo_password, ask("Enter sudo password: ") { |q| q.echo = false }
else
set :sudo_password, ENV['SUDO_PASSWORD']
end
xidel -s input.txt -e '{"data":[x:lines($raw) ! {"{SERVER}":.}]}'
{
"data": [
{
"{SERVER}": "server1"
},
{
"{SERVER}": "server2"
},
{
"{SERVER}": "server3"
},
{
"{SERVER}": "server4"
}
]
}
是x:lines($raw)
的简写。它会创建每行的数组。
用人类的术语来说,您可以看到tokenize($raw,'\r\n?|\n')
是“为每个新行创建一个JSON对象” 。
另请参阅this xidelcgi demo。