我试图对数组中每个字符串元素的最后三个字符进行 != 字符串比较,然后如果不相等则删除该元素,但它没有产生预期的结果。我确信我的代码不正确,因此我正在寻找一些有关如何纠正的指导。
我尝试了两个使用“==”和“!=”的示例来测试我的代码,如下所示:
大批:
array=(8669648574foo 86696485745u 231649bar 23164919a1 8594792682foo 859479268209t)
- 首先运行“==”
for ((i=0; i<${#array[@]}; i++)); do
chomp=${array[i]: -3}
echo chomp: $chomp
if [[ $chomp == "foo" ]] || [[ $chomp == "bar" ]]; then
echo "i: $i, element: ${array[i]}"
delete=${array[i]}
echo ${array[@]/$delete}
array=( "${array[@]/$delete}" )
fi
done
array=( "${array[@]}" )
echo "First run: ${array[@]}"
输出:(代码按预期工作,删除了 foo/bar 元素 - 但这不是我想要的)
chomp: foo
i: 0, element: 8669648574foo
86696485745u 231649bar 23164919a1 8594792682foo 859479268209t
chomp: 45u
chomp: bar
i: 2, element: 231649bar
86696485745u 23164919a1 8594792682foo 859479268209t
chomp: 9a1
chomp: foo
i: 4, element: 8594792682foo
86696485745u 23164919a1 859479268209t
chomp: 09t
First run: 86696485745u 23164919a1 859479268209t # expected result
第二次运行“!=”
for ((i=0; i<${#array[@]}; i++)); do
chomp=${array[i]: -3}
echo chomp: $chomp
if [[ $chomp != "foo" ]] || [[ $chomp != "bar" ]]; then
echo "i: $i, element: ${array[i]}"
delete=${array[i]}
echo ${array[@]/$delete}
array=( "${array[@]/$delete}" )
fi
done
array=( "${array[@]}" )
echo "Second run: ${array[@]}"
输出:(代码未按预期工作)
chomp: foo
i: 0, element: 8669648574foo
86696485745u 231649bar 23164919a1 8594792682foo 859479268209t
chomp: 45u
i: 1, element: 86696485745u
231649bar 23164919a1 8594792682foo 859479268209t
chomp: bar
i: 2, element: 231649bar
23164919a1 8594792682foo 859479268209t
chomp: 9a1
i: 3, element: 23164919a1
8594792682foo 859479268209t
chomp: foo
i: 4, element: 8594792682foo
859479268209t
chomp: 09t
i: 5, element: 859479268209t
Second run: # no output, deletes all elements.
注意:我也尝试过使用unset array[$i]
,但我超出了帖子大小,因此删除了这些示例。
问:如何删除不等于 foo/bar 的数组元素?
这是您的算法中的一个简单错误:因为
chomp
不能foo
同时bar
,该命令永远是真的。如果你写过
您将选择既不是 foo 也不是 bar 的元素。
这源自布尔代数的公式:
玩下面的数组
bash
0. 序言
小心使用
bash
作为编程语言!如果您计划处理大型条目,也许某些过滤器可能会更有效。对于样品:
删除以或结尾的行后,
$array
将从 , 的输出填充您的变量。yourCommand
foo
bar
问问自己是否需要将整个数组存储在变量中,或者是否必须将此输出作为流传递给任何下一个命令......
1. 快速放入(提交的)数组
恢复作业,删除除 not
bar
或 之外的所有内容foo
:抱歉,漏读了……
2.
unset
循环使用:注意:为了匹配同一变量的多个变体,最好使用
case
开关,而不是多个==
whith||
或&&
!请注意索引键:
1
、3
和5
,而不是0
、1
和2
。然后,反转作业:
3. 使用关联数组
该解决方案非常快,因为没有循环并且比第一个目的更强大。
但如果,代替
unset aArray[_foo] aArray[_bar]
你对于包含空格的字符串:
正如我在第一篇文章中提到的,我还尝试使用 unset:
输出:未预期
将其更改为 && 也没有按预期工作:
输出:额外不需要的元素
找到了解决方案(间接扩展 - 感谢 F. Hauri):
输出:预期结果
通过使用临时数组来保存要保留的数组元素,并利用该
[[ ... ]]
命令可用的模式匹配和逻辑运算符,可以实现更简单的问题解决方案。这个Shellcheck -clean 程序演示了这个想法:
程序输出:
declare -p var
是显示任何变量值的最佳方法之一,因为它以可用作 shell 代码的明确方式显示变量。