【问题标题】:check whether elements are present in list or not bash [duplicate]检查列表中是否存在元素 bash [重复]
【发布时间】:2015-10-06 15:06:01
【问题描述】:
  : ${models:=foo bar foobar baz}
  : ${special_list:=station_tracks user_features}

   for model in $models;

  do
      echo $model
    if # model in special list; then # how do i test this?
       # do something 
        continue

    fi
done

那么,基本上我如何测试变量模型是否在special_list 中?

【问题讨论】:

  • ...虽然models 在这里不是一个数组——它只是一个字符串,这使得它与其他问题有点不同——它应该是; IE。如果这是根据最佳实践编写的,它将是一个数组,并且是一个正确的副本。
  • 就个人而言,如果它的目的是快速查找,我会将special_list 构建为关联数组:declare -A special_list=( [station_tracks]=1 [user_features]=1 );然后,可以使用if [[ ${special_list[$model]} ]]在恒定时间内进行会员检查。

标签: bash shell


【解决方案1】:

Perl 有 SmartMatch operator ~~。和been noted 一样,Bash 和不 甚至 Awk 也有一个等价物,但是您可以使用 grep 作为解决方法。还 在我继续之前,如果您要使用 Bash 数组,请使用 Bash 数组。您的 一旦超出最简单的例子,语法就会严重崩溃, 像一个空间,参与进来:

models=(foo bar foobar baz)
special_list=(station_tracks user_features)
for model in "${models[@]}"
do
  echo "$model"
  if printf '%s\0' "${special_list[@]}" | grep -Fqxz "$model"
  then
    continue
  fi
done

如果您愿意,可以使用等效的长选项:

--fixed-strings --quiet --line-regexp --null-data

【讨论】:

  • “使用数组”的建议很好; “shell out to grep”的建议……这是一个相当大的性能损失。是的,grep 运行后会更快,但是 fork/exec 的恒定时间启动开销将在本机 bash 中购买大量 O(n) 迭代。
  • 嘿。我假设外部迭代是为了其他目的而需要的——你是对的,如果它只是为了连接的目的而进行的,那么我们就在一个不同的世界里。 (在这种情况下,我会考虑使用comm 而不是grep,因为每个模型只吃一次叉子开销)。
猜你喜欢
  • 2012-12-31
  • 2011-06-15
  • 2021-12-17
  • 2011-06-03
  • 2014-02-17
  • 1970-01-01
相关资源
最近更新 更多