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:
element_one
is in the bash array.element_two
is in the bash array.element_one
occurs before element element_two
in the array.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
}
#!./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"
}
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
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)?
Try bash-regexp:
$ arr=(one two)
$ [[ ${arr[@]} =~ one.*two ]] && echo ${BASH_REMATCH[@]}
one two
$ arr=(two one)
$ [[ ${arr[@]} =~ one.*two ]] && echo ${BASH_REMATCH[@]}