Bash,变量的行包含子字符串?
Bash, lines of a variable contain substring?
在尝试编写一个可靠的 bash 方法来检测由多行文本组成的变量是否包含子字符串(可能包含空格)时,我遇到了一些困难。编写了三个函数,我使用 BATS 框架为它们编写了一些测试。下面列出了它们失败的功能和附带的测试。
方法一
lines_contain_string() {
local substring=""
shift
local lines=("$@")
local found_substring="NOTFOUND"
for i in "${lines[@]}"; do
if [[ $i == *"$substring"* ]]; then
echo "FOUND"
local found_substring="FOUND"
fi
done
if [ "$found_substring" == "NOTFOUND" ]; then
echo "NOTFOUND"
fi
}
测试失败:
EXAMPLE_LINES=$(cat <<-END
First line
second line
third line
sometoken
END
)
@test "Substring in first line is found in lines by lines_contain_string." {
contained_substring="First line"
actual_result=$(lines_contain_string "$contained_substring" "${EXAMPLE_LINES}")
#actual_result=$(lines_contain_string_with_space "$contained_substring" "${EXAMPLE_LINES}")
EXPECTED_OUTPUT="FOUND"
assert_equal "$actual_result" "$EXPECTED_OUTPUT"
}
所以第一种方法没有捕获所有子字符串。
方法二
对于第二种方法:
lines_contain_string_with_space() {
local substring=""
local lines="$@"
if [ "$lines" == "" ]; then
echo "NOTFOUND"
# shellcheck disable=SC2154
elif [[ "$lines" =~ "$substring" ]]; then
echo "FOUND";
else
echo "NOTFOUND";
fi
}
这似乎 return 错误 positive/seems 总是 return “找到”,例如,在测试中:
EXAMPLE_LINES=$(cat <<-END
First line
second line
third line
sometoken
END
)
@test "lines_contain_string returns NOTFOUND on non-existing substring." {
contained_substring="Non-existing-substring"
#actual_result=$(lines_contain_string "$contained_substring" "${EXAMPLE_LINES}")
actual_result=$(lines_contain_string_with_space "$contained_substring" "${EXAMPLE_LINES}")
EXPECTED_OUTPUT="NOTFOUND"
assert_equal "$actual_result" "$EXPECTED_OUTPUT"
}
方法三
此方法由choroba提供:
string_in_lines() {
local substring=
shift
local lines=
if [[ $lines = *"$substring"* ]] ; then
echo FOUND
else
echo NOTFOUND
fi
}
并用测试调用它:
@test "Substring in first line is found in lines by lines_contain_string." {
contained_substring="First line"
read -p "EXAMPLE_LINES=$EXAMPLE_LINES"
#actual_result=$(lines_contain_string "$contained_substring" "${EXAMPLE_LINES}")
#actual_result=$(lines_contain_string_with_space "$contained_substring" "${EXAMPLE_LINES}")
actual_result=$(string_in_lines "$contained_substring" "${EXAMPLE_LINES}")
EXPECTED_OUTPUT="FOUND"
assert_equal "$actual_result" "$EXPECTED_OUTPUT"
}
产生输出:
✗ Substring in first line is found in lines by lines_contain_string.
(from function `assert_equal' in file test/no_server_required/preserves_server/../../libs/bats-assert/src/assert_equal.bash, line 40,
in test file test/no_server_required/preserves_server/test_parsing.bats, line 35)
`assert_equal "$actual_result" "$EXPECTED_OUTPUT"' failed
EXAMPLE_LINES=First line
second line
third line
sometoken
-- values do not equal --
expected : FOUND
actual : NOTFOUND
--
问题
如何根据由多行组成的传入变量是否包含可能包含空格的子字符串,在 bash 函数中回显“FOUND”/“NOTFOUND”? (并相应地进行测试。)
备注
由于我的测试在 choroba 提供的方法上也失败了,我认为成功的可能性很大,我预计我的测试功能不正确。我相应地更新了问题。
choroba 的评论建议反斜杠:`"${EXAMPLE_LINES}" 不正确。我测试了一下是不是不对,结果是不对。所以解决方案是将测试编写为:
@test "Substring in first line is found in lines by lines_contain_string." {
contained_substring="First line"
#actual_result=$(lines_contain_string "$contained_substring" "${EXAMPLE_LINES}")
#actual_result=$(lines_contain_string_with_space "$contained_substring" "${EXAMPLE_LINES}")
actual_result=$(string_in_lines "$contained_substring" "${EXAMPLE_LINES}")
EXPECTED_OUTPUT="FOUND"
assert_equal "$actual_result" "$EXPECTED_OUTPUT"
}
@test "lines_contain_string returns NOTFOUND on non-existing substring." {
contained_substring="Non-existing-substring"
#actual_result=$(lines_contain_string "$contained_substring" "${EXAMPLE_LINES}")
#actual_result=$(lines_contain_string_with_space "$contained_substring" "${EXAMPLE_LINES}")
actual_result=$(string_in_lines "$contained_substring" "${EXAMPLE_LINES}")
EXPECTED_OUTPUT="NOTFOUND"
assert_equal "$actual_result" "$EXPECTED_OUTPUT"
}
使用 =
和通配符模式。
string_in_lines() {
local substring=
shift
local lines=
if [[ $lines = *"$substring"* ]] ; then
echo FOUND
else
echo NOTFOUND
fi
}
在尝试编写一个可靠的 bash 方法来检测由多行文本组成的变量是否包含子字符串(可能包含空格)时,我遇到了一些困难。编写了三个函数,我使用 BATS 框架为它们编写了一些测试。下面列出了它们失败的功能和附带的测试。
方法一
lines_contain_string() {
local substring=""
shift
local lines=("$@")
local found_substring="NOTFOUND"
for i in "${lines[@]}"; do
if [[ $i == *"$substring"* ]]; then
echo "FOUND"
local found_substring="FOUND"
fi
done
if [ "$found_substring" == "NOTFOUND" ]; then
echo "NOTFOUND"
fi
}
测试失败:
EXAMPLE_LINES=$(cat <<-END
First line
second line
third line
sometoken
END
)
@test "Substring in first line is found in lines by lines_contain_string." {
contained_substring="First line"
actual_result=$(lines_contain_string "$contained_substring" "${EXAMPLE_LINES}")
#actual_result=$(lines_contain_string_with_space "$contained_substring" "${EXAMPLE_LINES}")
EXPECTED_OUTPUT="FOUND"
assert_equal "$actual_result" "$EXPECTED_OUTPUT"
}
所以第一种方法没有捕获所有子字符串。
方法二
对于第二种方法:
lines_contain_string_with_space() {
local substring=""
local lines="$@"
if [ "$lines" == "" ]; then
echo "NOTFOUND"
# shellcheck disable=SC2154
elif [[ "$lines" =~ "$substring" ]]; then
echo "FOUND";
else
echo "NOTFOUND";
fi
}
这似乎 return 错误 positive/seems 总是 return “找到”,例如,在测试中:
EXAMPLE_LINES=$(cat <<-END
First line
second line
third line
sometoken
END
)
@test "lines_contain_string returns NOTFOUND on non-existing substring." {
contained_substring="Non-existing-substring"
#actual_result=$(lines_contain_string "$contained_substring" "${EXAMPLE_LINES}")
actual_result=$(lines_contain_string_with_space "$contained_substring" "${EXAMPLE_LINES}")
EXPECTED_OUTPUT="NOTFOUND"
assert_equal "$actual_result" "$EXPECTED_OUTPUT"
}
方法三
此方法由choroba提供:
string_in_lines() {
local substring=
shift
local lines=
if [[ $lines = *"$substring"* ]] ; then
echo FOUND
else
echo NOTFOUND
fi
}
并用测试调用它:
@test "Substring in first line is found in lines by lines_contain_string." {
contained_substring="First line"
read -p "EXAMPLE_LINES=$EXAMPLE_LINES"
#actual_result=$(lines_contain_string "$contained_substring" "${EXAMPLE_LINES}")
#actual_result=$(lines_contain_string_with_space "$contained_substring" "${EXAMPLE_LINES}")
actual_result=$(string_in_lines "$contained_substring" "${EXAMPLE_LINES}")
EXPECTED_OUTPUT="FOUND"
assert_equal "$actual_result" "$EXPECTED_OUTPUT"
}
产生输出:
✗ Substring in first line is found in lines by lines_contain_string.
(from function `assert_equal' in file test/no_server_required/preserves_server/../../libs/bats-assert/src/assert_equal.bash, line 40,
in test file test/no_server_required/preserves_server/test_parsing.bats, line 35)
`assert_equal "$actual_result" "$EXPECTED_OUTPUT"' failed
EXAMPLE_LINES=First line
second line
third line
sometoken
-- values do not equal --
expected : FOUND
actual : NOTFOUND
--
问题
如何根据由多行组成的传入变量是否包含可能包含空格的子字符串,在 bash 函数中回显“FOUND”/“NOTFOUND”? (并相应地进行测试。)
备注
由于我的测试在 choroba 提供的方法上也失败了,我认为成功的可能性很大,我预计我的测试功能不正确。我相应地更新了问题。
choroba 的评论建议反斜杠:`"${EXAMPLE_LINES}" 不正确。我测试了一下是不是不对,结果是不对。所以解决方案是将测试编写为:
@test "Substring in first line is found in lines by lines_contain_string." {
contained_substring="First line"
#actual_result=$(lines_contain_string "$contained_substring" "${EXAMPLE_LINES}")
#actual_result=$(lines_contain_string_with_space "$contained_substring" "${EXAMPLE_LINES}")
actual_result=$(string_in_lines "$contained_substring" "${EXAMPLE_LINES}")
EXPECTED_OUTPUT="FOUND"
assert_equal "$actual_result" "$EXPECTED_OUTPUT"
}
@test "lines_contain_string returns NOTFOUND on non-existing substring." {
contained_substring="Non-existing-substring"
#actual_result=$(lines_contain_string "$contained_substring" "${EXAMPLE_LINES}")
#actual_result=$(lines_contain_string_with_space "$contained_substring" "${EXAMPLE_LINES}")
actual_result=$(string_in_lines "$contained_substring" "${EXAMPLE_LINES}")
EXPECTED_OUTPUT="NOTFOUND"
assert_equal "$actual_result" "$EXPECTED_OUTPUT"
}
使用 =
和通配符模式。
string_in_lines() {
local substring=
shift
local lines=
if [[ $lines = *"$substring"* ]] ; then
echo FOUND
else
echo NOTFOUND
fi
}