我正在编写一个可重复使用的Bash脚本,该脚本允许我查询API以获取有关议会成员的数据并以csv格式存储它。
API的json响应有很多键(名称,性别,生日,委员会成员,投票......),并且,根据我想做的事情,我并不总是希望捕获相同的键。所以我想抽象代码的这一部分,以便能够编写:
from PIL import Image
from numpy import array
def convert(arr, cont1, cont2, cont3, repet1, repet2, repet3):
if(cont1 != repet1):
if(cont2 != repet2):
if(cont3 != repet3):
test = arr[repet1][repet2][repet3]
if(test == 255):
arr[repet1][repet2][repet3] = 1
return convert(arr, cont1, cont2, cont3, repet1, repet2, repet3 +1)
else:
arr[repet1][repet2][repet3] = 0
return convert(arr, cont1, cont2, cont3, repet1, repet2, repet3 +1)
else:
return convert(arr, cont1, cont2, cont3, repet1, repet2 + 1, 0)
else:
return convert(arr, cont1, cont2, cont3, repet1 + 1, 0, 0)
else:
return arr
def convertAgain(binary, cont4, cont5, cont6, repet4, repet5, repet6):
if(cont4 != repet4):
if(cont5 != repet5):
if(cont6 != repet6):
test = binary[repet4][repet5][repet6]
if(test == 1):
binary[repet4][repet5][repet6] = 255
return convertAgain(binary, cont4, cont5, cont6, repet4, repet5, repet6 + 1)
else:
binary[repet4][repet5][repet6] = 0
return convertAgain(binary, cont4, cont5, cont6, repet4, repet5, repet6 + 1)
else:
return convertAgain(binary, cont4, cont5, cont6, repet4, repet5 + 1, 0)
else:
return convertAgain(binary, cont4, cont5, cont6, repet4 + 1, 0, 0)
else:
return binary
def main():
img = Image.open("put an image to try it")
arr = array(img)
len1 = len(arr)
len2 = len(arr[0])
len3 = len(arr[0][0])
binary = convert(arr, len1, len2, len3, 0, 0, 0)
print(binary)
new = convertAgain(binary, len1, len2, len3, 0, 0, 0)
print(new)
main();
这样它被jq解释为
mp_keys= a,b,c,d
curl https://mp.com | jq '. | [$mp_keys] | @csv'
我没有变量格式的集合结构,因此可能是:
jq '. | [.a, .b, .c, .d] | @ csv'
或mp_keys="a,b,c,d"
或mp_keys=".a, .b, .c, .d"
我知道在jq中我可以使用以下结构:
mp_key1=a, mp_key2=b, mp_key3=c, mp_key4=d
但很明显很快就会变得单调乏味。
最后我还可以将jq命令构建为字符串,然后将jq --arg mp_key1 "${mp_key1}" --arg mp_key2 "${mp_key2}" --arg mp_key3 "${mp_key3}" --arg mp_key4 "${mp_key4}" '.
| [.[$mp_key1], .[$mp_key2], .[$mp_key3], .[$mp_key4]]
| @csv'
应用于它,但我更喜欢使用正确的jq解决方案。
我将打破@ peak的回答以供将来参考,因为它对于了解发生了什么非常有用。他的回答转载如下:
eval
首先,了解jq会:
非常重要mp_keys="a,b,c,d"
echo '{"a":1, "b":2, "c":3, "d": 4}' |
jq -r --arg mpk "$mp_keys" '
($mpk|split(",")) as $mpkeys
| [ .[ $mpkeys[] ] ]
| @csv '
的值,这意味着在$mpkeys
上执行split(",")
$mpk
发送的json。所以我们也可以这样做,以了解发生了什么。 echo
告诉jq优先处理这个部分,所以我们可以先用括号替换它的结果。
( )
中的字符串"a,b,c,d"
将被拆分并存储到数组$mpk
中,如section on split(str)
of jq's manual中所述。["a","b","c","d"]
到$mpkeys
。这意味着初始代码的等价物可以写成:
as
当然现在--arg是无用的,因为echo '{"a":1, "b":2, "c":3, "d": 4}' |
jq -r --arg mpk "$mp_keys" '
["a","b","c","d] as $mpkeys
| [ .[ $mpkeys[] ] ]
| @csv '
可以保存我们的初始字符串。所以我们可以进一步简化:
$mpk
现在让我们分解echo '{"a":1, "b":2, "c":3, "d": 4}' |
jq -r '["a","b","c","d] as $mpkeys
| [ .[ $mpkeys[] ] ]
| @csv '
:
[ .[ $mpkeys[] ] ]
是一个数组,$mpkeys
代表数组的各个元素,相当于$mpkeys[]
。我们现在有4个元素(字符串),而不是单个元素(数组),它们将被它们周围的过滤器(括号)单独转换。"a","b","c","d"
包装到$mpkeys[]
中,该.[]
适用于4个元素中的每一个,因此相当于.["a"]
,.["b"]
,.["c"]
,{ {1}}。这些元素中的每一个都是通用对象索引,它等同于对象标识符索引形式(.["d"]
)为described in jq's manual。.a, .b, .c, .d
只是将数据包装在数组中,这是将结果传递给[ ]
所必需的。 所以相当于上面的代码是:
@csv
这里echo '{"a":1, "b":2, "c":3, "d": 4}' |
jq -r '["a","b","c","d] as $mpkeys
| [ .["a"], .["b"], .["c"], .["d"] ]
| @csv '
没有任何意义,所以我们实际上有:
$mpkeys
我们有。
答案 0 :(得分:1)
使用您的方法:
mp_keys="a,b,c,d"
echo '{"a":1, "b":2, "c":3, "d": 4}' |
jq -r --arg mpk "$mp_keys" '
($mpk|split(",")) as $mpkeys
| [ .[ $mpkeys[] ] ]
| @csv '
会产生:
1,2,3,4