2016-09-21 182 views
0

需要从JSON文件中提取每行两个变量,并在单独的后续命令中使用这两个变量中的每一个。在shell脚本中将bash变量传递给python命令

我的剧本是迄今为止:

#!/bin/bash 

VCTRL_OUT='/tmp/workingfile.json' 

old_IFS=$IFS  # save the field separator 
IFS=$'\n'  # new field separator, the end of line 

for line in $(cat $VCTRL_OUT) 
    do 
    python -c 'import json,sys;obj=json.load($line);print obj["ip_range"]' 
    done 

的倒数第二行是错误的,需要知道如何做到这一点。

以下工作:

cat /tmp/workingfile.json | head -n +1 | python -c 'import json,sys;obj=json.load(sys.stdin);print obj["ip_range"]'; 

,但不知道如何为循环做同样的bash脚本。

+0

bash中的单引号杀死所有特殊字符,甚至是$ line变量中的'$',所以不是变量的值,而是传递'“$ line”'字符串。你需要在'python -c ...'命令周围使用双引号。 – karlosss

+0

JSON文件是什么样的?比试图为文件的每一行运行单独的Python程序有更好的选择。 (忽略JSON不是面向行并且通常不能被逐行处理的这一事实,这是在'bash'中迭代文件的错误方法;请参见[Bash FAQ 001](http:// myjie.wooledge.org/BashFAQ/001)。) – chepner

+0

@karlosss - 现在运行的json.load命令现在不起作用,因为它是针对json行运行的。什么需要修改? – dross

回答

3

Python的不会是我对于这种只有一行的第一选择,但你可以尝试

#!/bin/bash 

VCTRL_OUT='/tmp/workingfile.json' 

parse_json() { 
    python -c $'import json,fileinput,operator\nfor line in fileinput.input(): print "%s %s"%operator.itemgetter("ip_range","description")(json.loads(line))' "$1" 
} 
while IFS= read -r ip_range description; do 
    # do your thing with ip_range 
done < <(parse_json "$VCTRL_OUT") 

一种选择是用jq更换的Python位:

while IFS= read -r ip_range description; do 
    # ... 
done < <(jq -rRc 'fromjson | .ip_range+" "+.description' "$VCTRL_OUT") 

另一个另一种方法是用Python替换整个bash脚本,但根据bash脚本的实际情况,说起来容易做起来难。