【发布时间】:2011-08-02 00:48:33
【问题描述】:
我有一个字符串
"name1:value1, ... name2:value2, ... name3:value3, ...",
我想将 value1、value2、value3 提取到 var1、var2、var3。 bash 或 python 中是否有简单的解决方案?越简单越好。
【问题讨论】:
-
托德:什么是var1、var2、var3?变量?新字符串的一部分?输出文件名?
我有一个字符串
"name1:value1, ... name2:value2, ... name3:value3, ...",
我想将 value1、value2、value3 提取到 var1、var2、var3。 bash 或 python 中是否有简单的解决方案?越简单越好。
【问题讨论】:
这是我的 bash 解决方案。我花了很多时间来确保它是最简单的:
string="name1:value1,name2:value2,name3:value3"
varCount=0
for nameValuePair in $( tr , ' ' <<< $string )
do
IFS=:
((varCount++))
set $nameValuePair
eval var$varCount="$2"
done
# Do what you want with $var1, $var2, ... For example:
echo var3=$var3
【讨论】:
$ echo "name1:value1, name2:value2, name3:value3" | awk -F",[ \t]*" '{for(i=1;i<=NF;i++){split($i,a,":");print a[2] } }'
value1
value2
value3
$ echo "name1:value1, name2:value2, name3:value3" | ruby -e 'print gets.split(",").each{|x| puts x.split(":")[-1]}'
value1
value2
value3
要捕获到shell变量,
$ var=$(echo "name1:value1, name2:value2, name3:value3" | awk -F",[ \t]*" '{for(i=1;i<=NF;i++){split($i,a,":");print a[2] } }')
$ echo $var
value1 value2 value3
$ set -- $var
$ echo $1
value1
$ echo $2
value2
@Todd,请查看 bash 参考。
set [--abefhkmnptuvxBCEHPT] [-o option] [arg ...] .....
... Any arguments remaining after option processing are treated as values for the positional parameters and are assigned, in order, to
$1, $2, ... $n..
-- If no arguments follow this option, then the positional parameters are unset. Otherwise, the positional parameters are
set to the args, even if some of them begin with a -.
【讨论】:
纯猛击:
declare string="name1:value1, name2:value2, name3:value3, name4:value4"
IFSsave=$IFS
IFS=','
declare -a array=( $string ) # split string into array
IFS=$IFSsave
for item in ${array[@]}; do
item=${item/:/=} # substitute ':' to '='
eval "${item/#name/var}" # substitute 'name' to 'var'
done
echo -e "the new variables : ${!var*}"
for v in ${!var*}; do
echo -e "$v = ${!v}" # use indirect parameter expansion
done
输出:
the new variables : var1 var2 var3 var4
var1 = value1
var2 = value2
var3 = value3
var4 = value4
【讨论】:
>>> s = "name1:value1,name2:value2, name3:value3"
>>> d = dict(e.split(':') for e in s.split(','))
>>> for count, values in zip(range(1, len(d)+1), sorted(d.itervalues())):
... globals()['var{0}'.format(count)] = values
...
>>> var1
'value1'
>>> var2
'value2'
>>> var3
'value3'
相当 hack-ish,我知道,但是如果有更清洁的方法,请随时提出建议 :-)(注意:这是一个通用解决方案,如果您需要字典的键,您也可以使用它略有变化)
编辑:基于托马斯的评论:
>>> s = "name1:value1,name2:value2, name3:value3"
>>> d = dict(e.split(':') for e in s.split(','))
>>> d
{'name2': 'value2', ' name3': 'value3', 'name1': 'value1'}
>>> d['name2']
value2
【讨论】:
globals() 的变异真的没有必要(并且在函数中做了错误的事情。)只需保留 dict 并使用它。
当你有一个像"name1:value1, ... name2:value2, ... name3:value3, ..." 这样的字符串时
然后你可以这样做来听写:
d = eval('{'+"name1:value1, ... name2:value2, ... name3:value3, ..."+'}')
然后:
>>> print d['name1']
value1
...
【讨论】:
eval?真的吗?手动提取值更安全、更健壮、更灵活且更易于理解。如果您必须将其传递给其他东西进行评估,请改用json 或ast.literal_eval。