【问题标题】:extract multiple fields from a string从字符串中提取多个字段
【发布时间】:2011-08-02 00:48:33
【问题描述】:

我有一个字符串

"name1:value1, ... name2:value2, ... name3:value3, ...",

我想将 value1、value2、value3 提取到 var1、var2、var3。 bash 或 python 中是否有简单的解决方案?越简单越好。

【问题讨论】:

  • 托德:什么是var1、var2、var3?变量?新字符串的一部分?输出文件名?

标签: python bash sed awk


【解决方案1】:

这是我的 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

【讨论】:

    【解决方案2】:
    $ 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 -.
    

    【讨论】:

    • “$ set -- $var”是什么意思?
    【解决方案3】:

    纯猛击:

    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
    

    【讨论】:

      【解决方案4】:
      >>> 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 并使用它。
      • @Thomas:嗯,好的。我会更新。不过,我仍然不完全确定 OP 想要什么。
      【解决方案5】:

      当你有一个像"name1:value1, ... name2:value2, ... name3:value3, ..." 这样的字符串时 然后你可以这样做来听写: d = eval('{'+"name1:value1, ... name2:value2, ... name3:value3, ..."+'}') 然后:

      >>> print d['name1']
      value1
      ...
      

      【讨论】:

      • eval?真的吗?手动提取值更安全、更健壮、更灵活且更易于理解。如果您必须将其传递给其他东西进行评估,请改用jsonast.literal_eval
      • 好的,但我不知道他从哪里得到数据。当他信任源时,可以使用 eval()。这很好。
      • 这里name1、name2等不需要引用字符串,eval才能工作?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      相关资源
      最近更新 更多