在 bash 中找不到标记时无法获取空子字符串

Can't get empty substring when no token found in bash

我正在尝试在 bash

中的标记“-”之后获取子字符串

我有以下功能:

STR="abc-def"
END=`echo $STR | cut -d "-" -f2`
echo $END # prints def (OK)

STR="abc"
END=`echo $STR | cut -d "-" -f2`
echo $END # prints abc (ERROR)

STR="abc-abc"
END=`echo $STR | cut -d "-" -f2`
echo $END # prints abc (OK)

如何修复它,以便在找不到“-”时得到 END=""?

您可以测试您的字符串以检查它是否完全包含分隔符:

[[ "${STR}" == *"-"* ]] && END=$(echo $STR | cut -d "-" -f2) || END = ""

如果您更喜欢(在本例中不是那么神秘)正则表达式方法:

[[ "${STR}" =~ "-" ]] && END=$(echo $STR | cut -d "-" -f2) || END = ""

更新:在我最初的解决方案中,我错误地假设“END”应该保留前导连字符,但我只是注意到情况并非如此。我现在已经更新了我的解决方案,新版本变得更简单了:

这里不需要生成子进程。基本上你可以做一个

END=${STR#*-}

# 之后的 glob 模式删除了第一个 - 之前的所有内容。这仍然使问题悬而未决,如果 STR 不包含连字符,您将返回原始字符串,而不是空字符串。

由于您已将问题标记为 bashshell,我将针对这两个问题提出解决方案.

在bash中,你可以简单地做一个

if [[ $STR == *-* ]]
then
  END="${STR#*-}"
else
  END=
fi

由于[[不是外部命令,所以这也不需要子进程。

在POSIXshell中,我会做一个

END="${STR#*-}" # Remove up to (including) hyphen
if [ "$END" = "$STR" ]
then
  # We did not have a hyphen
  END=
fi

这会生成一个子进程([),因此它比 bash 版本成本更高。

将'-'更改为''

STR=${STR//-/' '}

将 STR 转换为数组

STR=( $STR )

将第 2 项分配给 END

END=${STR[1]}

如果第 2 个项目存在,则 END 将为 'def' 如果不存在,则 END 将为空。单线

STR="abc-def"; STR=( ${STR//-/' '} ); END=${STR[1]}; echo $END

如果 left\right 或两边有空格,更改 IFS 会有帮助

IFS=-; STR='ab x-de f'; ARR=( $STR ); END=${ARR[1]}; echo $END

或者你可以先转换空格,最后再转换回来

STR='ab x-de f'; STR=${STR//' '/_SPACE_}; STR=${STR//-/' '}; ARR=( $STR ); END=${ARR[1]}; echo ${END//_SPACE_/' '}