【问题标题】:Validate a string against an array根据数组验证字符串
【发布时间】:2020-12-23 23:09:59
【问题描述】:

我有一个这样的字符串:

array_string="a b"

我有一个这样的数组:

array=(a b c)

我想验证 array_string 的所有元素是否都包含在数组中,如果这样我可以用 array_string 中包含的元素覆盖数组:

array=($array_string)

进行此类验证的最佳方法是什么?

【问题讨论】:

  • 这个没有内置操作。您需要将array_string 转换为数组,然后使用嵌套循环来测试它们是否都在array 中。
  • bash 没有运算符来测试字符串是否在数组中。如果您经常需要这样的复杂数组操作,bash 不是正确的语言。
  • 为什么array_string 应该包含多个单词但存储在一个变量中?如果其中一个单词包含空格怎么办?这种设计本身就有缺陷。您应该维护两个单独的数组
  • @Inian 数组字符串作为环境变量传递。这是我无法更改的要求

标签: arrays linux bash


【解决方案1】:

您可以将grep 与几个进程替换一起使用:

grep -qvf <(printf '%s\n' "${array[@]}") <(echo "${array_string// /$'\n'}") ||
echo "all elements of array_string are present in array"

【讨论】:

    【解决方案2】:

    对于字符串到数组的比较,以下示例使用空格作为分隔符,并希望它位于列表的开头和结尾,这样每个值都将被包裹在两个分隔符之间。它还避免使用外部进程或子shell。

    for ((index=0; index < "$((${#array[@]}"; index++)); do
      if [[ "$array_string" != *" ${array[$index]} "* ]]; then
        return 1
      fi
    done
    

    对于数组到数组的比较,很容易在删除前导分隔符后将字符串转换为数组,然后使用嵌套循环来比较它们。这也可以避免使用外部进程或子shell,因为读取的是bash builtin

    # Needs to read to a different variable so it
    #   doesn't empty the source and read nothing.
    IFS=' ' read -ra string_array <<< "${array_string# }"
    found=1
    for ((x=0; x < "${#string_array[@]}"; x++)); do
      for ((y=0; y < "${#array[@]}"; y++)); do
        if [[ "${string_array[$x]}" == "${array[$y]}" ]]; then
          found=0
        fi
      done
    
      if [[ found -ne 0 ]]; then
        return 1
      fi
    
      found=1
    done
    

    【讨论】:

      【解决方案3】:

      您可以像这样确定array_string 中存在但array 中不存在的项目:

      join -v1 <(sort -b <<< "${array_string// /$'\n'}") <(IFS=$'\n'; sort -b <<< "${array[*]}")
      

      假设项目不包含空格。 使用它,您可以:

      if [[ -z $(join -v1 <(sort -b <<< "${array_string// /$'\n'}") <(IFS=$'\n'; sort -b <<< "${array[*]}")) ]]
      then
          echo "array_string is a subset of array"
      else
          echo "array_string is NOT a subset of array"
      fi
      

      【讨论】:

        猜你喜欢
        • 2016-06-05
        • 1970-01-01
        • 2018-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多