有没有更好的方法来检查两个字符串是否相等而忽略给定的分隔符,例如:
function is_equal() {
local str1="$1"
local delim1="$2"
local str2="$3"
local delim2="$4"
IFS=$delim1 read -r -a array1 <<< "$str1"
IFS=$delim2 read -r -a array2 <<< "$str2"
if [[ ${#array1[@]} -ne ${#array2[@]} ]]; then
return 1
fi
str1raw=$(IFS='' echo "${array1[*]}")
str2raw=$(IFS='' echo "${array2[*]}")
if [ "${str1raw}" != "${str2raw}" ]; then
return 1
fi
return 0
}
is_equal "!etc!daemon!sys.conf" "!" "/etc/daemon/sys.conf" "/"
这有效,但我不想使用数组。
答案 0 :(得分:5)
只要您的字符串包含文本数据(仅指可打印的字符)是安全的,您可以使用参数扩展在比较之前用不可打印的字符替换分隔符。这样做两个字符串在比较期间共享相同的分隔符:
if [ "${str1//$delim1/\\x01}" = "${str2//$delim2/\\x01}" ] ; then
echo "strings are equal"
fi
我使用不可打印的字符作为分隔符,以确保分隔符不会成为数据本身的一部分。
答案 1 :(得分:1)
您需要使用数组。通常,数组用于存储一组项目,这些项目可能是您想要分隔两个项目的任何字符。在这里,你有一个共同的问题:每个字符串本身已经有一个安全的分隔符,但是那个elimiter对另一个字符串不一定安全。
为了进行分量比较,你需要选择一个对两者都安全的公共分隔符 - 这将我们带回到引入问题数组来解决。
答案 2 :(得分:0)
如果你真的想避免使用数组,你可以这样做:
function is_equal {
local str1="$1"
local delim1="$2"
local str2="$3"
local delim2="$4"
diff <( tr -d "$delim1" <<< "$str1" ) \
<( tr -d "$delim2" <<< "$str2" ) > /dev/null 2>&1
}
它可能会更慢,但它更短更容易阅读恕我直言。