【问题标题】:Associative array from querystring in bash?bash中查询字符串的关联数组?
【发布时间】:2014-03-27 06:50:05
【问题描述】:

如何从 Bash 中的查询字符串中获取关联数组? - 尝试:

#!/usr/bin/env bash

# Querystring (implementation stolen from http://stackoverflow.com/q/3919755)

function populate_querystring_array ()
{
    param="$1"
    query_dict="$2"
    #for i in "${array[@]}"; do IFS="=" ; set -- $i; query_dict[$1]=$2; done

    for ((i=0; i<${#param[@]}; i+=2))
    do
        query_dict[${param[i]}]=${param[i+1]}
    done
}

q0='email=foo@bar.com&password=dfsa54'
declare -A querydict
populate_querystring_array "$q0" "$querydict"
printf "$querydict[email]"

【问题讨论】:

    标签: bash query-string associative-array bash4 ifs


    【解决方案1】:

    接受@John1024 的回答,我在一个按值返回关联数组的函数中使用它,只需使用数组语法打印出内容:

    function parseQuery {
        local querystring="$*"
        echo -n "("
        echo "${querystring}" | sed 's/&/\n/g' | while IFS== read arg value
        do
            echo -n "[${arg}]='${value}' "
        done
        echo ")"
    }
    
    declare -A querydict=$(parseQuery "${QUERY_STRING}" )
    

    【讨论】:

      【解决方案2】:

      以下应该可以:

      #!/bin/bash
      
      function qrystring() {
          qry=$1
      
          while read key value; do
              arr+=(["$key"]="$value")
          done < <(awk -F'&' '{for(i=1;i<=NF;i++) {print $i}}' <<< $qry | awk -F'=' '{print $1" "$2}')
      }
      
      q='email=foo@bar.com&password=dfsa54'
      declare -A arr
      
      qrystring "$q"
      
      for k in ${!arr[@]}; do
          echo "$k -> ${arr[$k]}"
      done
      

      解释:

      我使用 awk 命令的组合首先将字符串拆分为单独的记录,然后在 = 符号上拆分 kv 对。

      我在这里使用进程替换,否则我将填充数组的副本。

      编辑:

      使用全局变量来存放数组。

      【讨论】:

      • Tim 和@AT,只是一个小问题:您可能想要删除声明 arr=$2。这是因为,当 bash 执行语句 qrystring "$q" "$arr" 时,第二个参数的计算结果为空字符串(因为此时 arr 为空)。因此,赋值语句arr=$2arg[0]0 是未指定时的默认索引)设置为空字符串。其效果在最终的for 循环中可见,该循环将字符串0 -&gt; 作为其中一行输出。
      【解决方案3】:
      #!/usr/bin/env bash
      q0='email=foo@bar.com&password=dfsa54'
      declare -A querydict
      while IFS== read key value
      do
          querydict["$key"]="$value"
      done < <(echo "$q0" | sed 's/&/\n/g' )
      printf "${querydict[email]}\n"
      

      在上面,'s/&amp;/\n/g' 是一个sed 命令,它将每次出现的&amp; 替换为一个新行。我们将此应用于q0,以便每个参数分配都在单独的行上。然后将参数分配读入while 循环。要阅读每个作业,请使用IFS== read key valueIFS== 告诉 read 将等号视为单词分隔符。因此,每个分配都分为两个词:第一个是键,第二个是值。然后使用语句querydict["$key"]="$value" 将它们分配给关联数组querydict

      把它放在一个函数中

      bash 与大多数现代编程语言的不同之处在于,它用于将复杂数据传入和传出函数的功能极为有限。在如下所示的方法中,关联数组querydict是一个全局变量:

      #!/usr/bin/env bash
      declare -A querydict
      populate_querystring_array () {
          query="$1"
          while IFS== read arg value
          do 
              querydict["$arg"]="$value"
          done < <(echo "$query" | sed 's/&/\n/g' )
      }
      
      q0='email=foo@bar.com&password=dfsa54'
      populate_querystring_array "$q0"
      printf "${querydict[email]}\n"
      

      【讨论】:

      • 谢谢,但我无法让它在函数中工作。 See ideone.
      • @AT bash 比你想象的要原始得多。 bash 不包含您可能期望从其他编程语言中获得的功能。我确实在答案中添加了一个带有函数的bash 解决方案,但请注意它使用了一个共享的全局变量。
      • 宁愿传递参数。如果这不可能,我可以使用unset $querydict 清空查询字典;正确的? - 编辑:看起来有 a hack 让它工作
      • @AT 如果您使用unset,您将丢失declare -A 定义。如果您只想清空它,请使用querydict=()。您链接到的那个黑客使用eval,这是人们努力避免的事情。为什么你如此强烈地想把这个简单的四行循环放在一个函数中?
      • 因为我在很多地方都需要这个功能。
      猜你喜欢
      • 1970-01-01
      • 2021-11-04
      • 2020-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多