英文:
How to check order of two elements in bash array?
问题
如何在Bash中编写一个函数来检查某个元素one
是否出现在另一个元素two
之前(同时验证这两个元素都在数组中)?
你可以使用以下的Bash函数来实现这一功能:
check_element_order() {
local array=("$@") # 将传入的参数转换为数组
local element_one="$1"
local element_two="$2"
local found_one=false
local found_two=false
for item in "${array[@]}"; do
if [ "$item" = "$element_one" ]; then
found_one=true
elif [ "$item" = "$element_two" ]; then
found_two=true
fi
if [ "$found_two" = true ] && [ "$found_one" = false ]; then
echo "element_one occurs before element_two"
return 0 # 返回成功状态码
fi
done
if [ "$found_one" = true ] && [ "$found_two" = false ]; then
echo "element_one occurs after element_two"
return 0 # 返回成功状态码
fi
echo "element_one and element_two not found in the array"
return 1 # 返回失败状态码
}
# 用法示例:
my_array=("one" "two" "three" "four")
check_element_order "two" "three" "${my_array[@]}"
这个函数首先将传入的参数转换为数组,然后遍历数组,查找元素one
和元素two
。如果找到元素two
而没有找到元素one
,则返回"element_one occurs before element_two"。如果找到元素one
而没有找到元素two
,则返回"element_one occurs after element_two"。如果两个元素都没有找到,返回"element_one and element_two not found in the array"。根据返回的状态码,你可以在调用该函数后进行进一步的处理。
英文:
Context
After having written a method that checks whether element element_one
occurs before element element_two
in a comma separated list (in string format in Bash), I am experiencing some difficulties in converting the code and tests into a function that:
- Verifies element
element_one
is in the bash array. - Verifies element
element_two
is in the bash array. - Verifies element
element_one
occurs before elementelement_two
in the array.
Code
element_one_before_two_in_csv() {
local elem_one
elem_one="$1"
local elem_two
elem_two="$2"
local csv_array
csv_array="$3"
IFS=, read -r -a arr <<<"${csv_array}"
local found_one
local found_two
assert_csv_array_contains_element "$elem_one" "$csv_array"
assert_csv_array_contains_element "$elem_two" "$csv_array"
for item in "${arr[@]}"; do
if [[ $elem_one == "$item" ]]; then
found_one="FOUND"
fi
if [[ $elem_two == "$item" ]]; then
found_two="FOUND"
fi
if [[ "$found_two" == "FOUND" ]] && [[ "$found_one" != "FOUND" ]]; then
echo "AFTER"
break
elif [[ "$found_one" == "FOUND" ]] && [[ "$found_two" != "FOUND" ]]; then
echo "BEFORE"
break
fi
done
}
assert_csv_array_contains_element() {
local elem_one
elem_one="$1"
local csv_array
csv_array="$2"
if [[ "$(csv_array_contains_element $elem_one $csv_array)" != "FOUND" ]]; then
echo "Error, did not find element:$elem_one in: $csv_array"
exit 6
fi
}
csv_array_contains_element() {
local elem_one
elem_one="$1"
local csv_array
csv_array="$2"
IFS=, read -r -a containing_arr <<<"${csv_array}"
local found_one
for item in "${containing_arr[@]}"; do
if [[ "$elem_one" == "$item" ]]; then
found_one="FOUND"
echo "FOUND"
fi
done
if [[ $found_one != "FOUND" ]]; then
echo "NOTFOUND"
fi
}
Tests
#!./test/libs/bats/bin/bats
load 'libs/bats-support/load'
load 'libs/bats-assert/load'
@test "element_one_before_two_in_csv returns BEFORE for correct found order." {
source ./src/helper.sh
# Run function that is tested.
run element_one_before_two_in_csv "two" "three" "one,two,three,four"
assert_output "BEFORE"
}
@test "element_one_before_two_in_csv returns AFTER for swithced order." {
source ./src/helper.sh
run element_one_before_two_in_csv "three" "two" "one,two,three,four"
assert_output "AFTER"
}
@test "element_one_before_two_in_csv raises error if first element is missing." {
source ./src/helper.sh
run element_one_before_two_in_csv "banana" "two" "one,two,three,four"
assert_failure
assert_output -p "Error, did not find element:banana in: one,two,three,four"
}
@test "element_one_before_two_in_csv raises error if second element is missing." {
source ./src/helper.sh
run element_one_before_two_in_csv "four" "banana" "one,two,three,four"
assert_failure
assert_output -p "Error, did not find element:banana in: one,two,three,four"
}
Output
bats test
test_array_order.bats
✓ element_one_before_two_in_csv returns BEFORE for correct found order.
✓ element_one_before_two_in_csv returns AFTER for switched order.
✓ element_one_before_two_in_csv raises error if first element is missing.
✓ element_one_before_two_in_csv raises error if second element is missing.
4 tests, 0 failures
Question
Hence, I would like to ask:
*How can a function in bash check whether some element one
occurs before some element two
in a bash array (whilst verifying both elements one
and two
are in the array)?
答案1
得分: 1
Try bash-regexp:
$ arr=(one two)
$ [[ ${arr[@]} =~ one.*two ]] && echo ${BASH_REMATCH[@]}
one two
$ arr=(two one)
$ [[ ${arr[@]} =~ one.*two ]] && echo ${BASH_REMATCH[@]}
英文:
Try bash-regexp:
$ arr=(one two)
$ [[ ${arr[@]} =~ one.*two ]] && echo ${BASH_REMATCH[@]}
one two
$ arr=(two one)
$ [[ ${arr[@]} =~ one.*two ]] && echo ${BASH_REMATCH[@]}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论