Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用pythonshlex解析bash数组? 输入: 期望输出_Python_Arrays_Bash_Lexical Analysis_Shlex - Fatal编程技术网

如何使用pythonshlex解析bash数组? 输入: 期望输出

如何使用pythonshlex解析bash数组? 输入: 期望输出,python,arrays,bash,lexical-analysis,shlex,Python,Arrays,Bash,Lexical Analysis,Shlex,我想得到这个输出: { 'ForwardPort': [ '"L *:9102:10.0.1.8:9100 # remote laptop"', '"L *:9166:8.8.8.8:9100 # google"' ] } 企图 我试着玩一下shlex,但是数组的解析非常糟糕: import shlex line='ForwardPort=([0]="L *:9102:10.0.1.8:9100 # remote laptop" [1

我想得到这个输出:

{
    'ForwardPort': [ 
        '"L *:9102:10.0.1.8:9100 # remote laptop"', 
        '"L *:9166:8.8.8.8:9100 # google"'
        ]
}
企图 我试着玩一下
shlex
,但是数组的解析非常糟糕:

import shlex
line='ForwardPort=([0]="L *:9102:10.0.1.8:9100 # remote laptop" [1]="L *:9166:8.8.8.8:9100 # google")'
lex=shlex.shlex(line)
list(lex)
['ForwardPort', '=', '(', '[', '0', ']', '=', '"L *:9102:10.0.1.8:9100 # remote laptop"', '[', '1', ']', '=', '"L *:9166:8.8.8.8:9100 # google"', ')']
问题: 有没有办法将
ForwardPort
的值自动解析到列表中


注意:不要在家里复制这是一个糟糕的设计决策,导致了这个复杂的问题:S

您可以在bash中使用以下命令打印出来:

#!/bin/bash

declare -a ForwardPort=([0]="L *:9102:10.0.1.8:9100 # remote laptop" [1]="L *:9166:8.8.8.8:9100 # google")
res=$(python -c 'import json, sys; print(json.dumps({"ForwardPort": [v for v in sys.argv[1:]]}))' "${ForwardPort[@]}")
echo "$res"
给出:

{"ForwardPort": ["L *:9102:10.0.1.8:9100 # remote laptop", "L *:9166:8.8.8.8:9100 # google"]}

如果您在python中将bash数组定义为字符串,则可以尝试以下有点粗糙的解析:

import re

line='ForwardPort=([0]="L *:9102:10.0.1.8:9100 # remote laptop" [1]="L *:9166:8.8.8.8:9100 # google")'

name, arr = line.split('=(')
arr = arr[:-1]  # removing the trailing ')'
lst = [item for item in re.split('\[\d+\]=', arr) if item]

dct = {name: lst}
print(dct)

从Python开始,然后从那里启动bash(实际上与从bash启动Python的操作相反):

使用创建如下的输入文件进行测试:

cat >file.txt <<'EOF'
declare -a ForwardPort=([0]="L *:9102:10.0.1.8:9100 # remote laptop"
                        [1]="L *:9166:8.8.8.8:9100  # google")
EOF

您从哪里获得
转发端口
?看起来您正在穿越两种不同的语言。您的“ForwardPort”采用bash数组格式有什么原因吗?
shlex.shlex
是一个lexer,它将返回一个令牌列表,由您来解析,……此外,
shlex
是为POSIX sh定义的。bash不是这样。如果您只解析单行字符串,请使用regex,如果您需要上下文/多行解析,我建议PyParsing后退一步,是什么生成了该输入?为什么它不能为Python(或任何其他语言)生成更有用的东西呢?顺便说一句,我序列化Python要解析的bash数组的通常方法是使用NUL分隔符:
printf'%s\0'${array[@]}”
,然后您的Python代码就可以在NUL上拆分。但就像这个答案一样,这取决于实际调用bash来完成工作。@hiroprotation我正在从Python上下文加载bash@ÉdouardLopez:试图在Python中解析它。这就是你要找的吗?
import subprocess

print_array_script=r'''
source "$1" || exit
declare -n arrayToPrint=$2 || exit
printf '%s\0' "${arrayToPrint[@]}"
'''

def bashArrayFromConfigFile(scriptName, arrayName):
    return subprocess.Popen(['bash', '-c', print_array_script, '_', scriptName, arrayName],
                            stdout=subprocess.PIPE).communicate()[0].split('\0')[:-1]

print(bashArrayFromConfigFile('file.txt', 'ForwardPort'))
cat >file.txt <<'EOF'
declare -a ForwardPort=([0]="L *:9102:10.0.1.8:9100 # remote laptop"
                        [1]="L *:9166:8.8.8.8:9100  # google")
EOF
['L *:9102:10.0.1.8:9100 # remote laptop', 'L *:9166:8.8.8.8:9100  # google']