【问题标题】:Compare array elements with an element将数组元素与元素进行比较
【发布时间】:2021-03-10 14:47:17
【问题描述】:

我正在尝试将一个数组与一个值进行比较,如果未找到匹配项,则打印一条错误语句。

arraylist="$(ls new-dir/ | cut -d' ' -f1)"

例如,它存储诸如小、大和中等值,它们是存在于new-dir 中的文件。 要与之比较的值将由用户输入,即。变量

我尝试过类似以下的方法:

(for i in "${arraylist[@]}"; do [[ "$i" == "$var"]] && exit 0; done) && echo "found" || echo "not found"

也试过了,还是不行:

arraylist="$(ls new-dir/ | cut -d' ' -f1)"
count=0

for((i=0; i<${#arraylist[@]}; i++)); do
  if [ "$arraylist[$i]" == "$var" ] ; then
    count=1
  fi
done

if [ $count -eq 0 ]; then
  echo "Not found"
fi

还有其他方法可以进行这种比较吗?

【问题讨论】:

  • 您访问数组元素的语法错误。它应该是${arraylist[$i]}${arraylist[i]},因为这是一个索引数组。还有,Why you shouldn't parse the output of ls.
  • 上面的整个sn-p可以简化为[[ -e new-dir/$var ]] || echo "Not found"(如果语法正确的话)。
  • arraylist="$( 这不是一个数组。这是一个正常的变量。 stackoverflow.com/questions/3685970/… 回答你的问题?
  • 感谢您的帮助。有什么方法可以从目录中获取文件并将其存储在一个数组中而无需手动形成一个?
  • @AishwaryaK 我不知道“无需手动成型”是什么意思,但这很容易做到:files=(dirname/*)。请注意,该数组还将包含非常规文件(如果有),并且默认情况下不包含以. 开头的文件名。

标签: arrays linux bash shell


【解决方案1】:

此代码有效。只需将 arraylist 替换为您的数组即可。

arraylist=('hello' 'world')
var='hello'
count=0

for i in "${arraylist[@]}"
do
    if [ "$i" == "$var" ]; then
        count=1
    fi
done

if [ $count -eq 0 ]; then
  echo "Not found"
fi

【讨论】:

  • 最好在count=1之后的第一场比赛中中断,因为不需要继续循环。
【解决方案2】:

要从每个文件名中提取第一个“单词”,我会这样做

declare -A prefixes
cd new-dir
for file in *; do
    read -r prefix _ <<< "$file"
    prefixes["$prefix"]=1
done
cd -

然后寻找匹配:

# $var is somehow provided
result=""
for p in "${!prefixes[@]}"; do
  if [[ $p == "$var" ]]; then
    result=found
    break
  fi
done
echo "${result:-not found}"

这需要 bash v4.0+ 才能使用关联数组。

如果你有 bash v4.3+,你可以这样做

[[ -v prefixes[$var] ]] && echo found || echo not found

交替:

shopt -s nullglob
files=( new-dir/"$var "* )
(( ${#files[@]} > 0 )) && echo found || echo not found

【讨论】:

    【解决方案3】:

    这就是 shell 编程的意义所在。保持简单:

    Array1=( "item1" "item2" "item3" "item-4" )
    var="item3"
    
    count=$(echo ${Array1[@]} | tr ' ' '\n' | awk '$1 == "'"$var"'"{print $0}' | wc -l)
    [ $count -eq 0 ] && echo "Not found" || echo "found"
    

    【讨论】:

    • 我投了反对票,只是因为我觉得这个答案没有用,而且在很多情况下它可能会失败;例如,当数组元素包含空格或通配符时。而且我的评论并不是一个解决方案。
    【解决方案4】:

    arraylist 可能是一个只有一个索引的数组。

    命令: arraylist="$(ls new-dir/ | cut -d' ' -f1)" 可能只是将整个“ls new-dir”输出分配给${arraylist[0]}

    您可以通过echo ${arraylist[1]}(确认)检查数组中的索引值。

    尝试将生成文件/目录列表数组的命令更改为:

    arraylist=($(ls new-dir/))
    

    完整的脚本:

    
    arraylist=($(ls new-dir/))
    
    (for i in "${arraylist[@]}"; do [[ "$i" == "$var" ]] && exit 0; done) && echo "found" || echo "not found"
    

    你也可以忽略整个数组赋值,只在 for 循环中使用 subshel​​l-command,例如:

    (for i in $(ls -1 new-dir/); do [[ "$i" == "$var" ]] && exit 0; done) && echo "found" || echo "not found"
    

    记住," 周围没有引号 $(ls -1 new-dir/)


    另一个没有任何数组或循环的单行:

    ls -1 new-dir/ | grep -q "$var" && echo "found" || echo "not found"
    

    编辑: 作为@M。 Nejat Aydin 建议使用[[ -e new-dir/$var ]] &amp;&amp; echo "found" || echo "Not found"do not use ls in the script

    【讨论】:

    • “一个简单的单行”如果没有外部命令lsgrep 和子shell:[[ -e k8s_apps/$var ]] &amp;&amp; echo "found" || echo "Not found" 可能会更简单
    • @M.NejatAydin 好吧,您已经分享了与对 OP 问题的评论相同的单行字。我认为重复答案不是一个好主意。这里的想法是提供替代方案。
    • 问题是,它不是替代品;在很多情况下它可能会失败。例如,变量var 可能包含空格或通配符(如*)。文件名也可能包含一些奇怪的字符。使用ls 不是获取脚本中文件列表的正确方法。
    猜你喜欢
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多