在 Bash 中,如何获取字符串中子字符串的位置,从字符位置 n 开始搜索

在 Bash 中,如何获取字符串中子字符串的位置,从字符位置 n 开始搜索

我是 Bash 脚本的新手,以前我在 Windows 中使用过 Visual Basic,正在寻找 VB 的 Bash 等效字符串函数inStr()

VB 示例:

strMain = "abcABC123ABCabc"
searchStartPos = 6   'Start searching at 6th char.
subStr = "AB"        'Look for "AB".

pos = inStr(searchStartPos, strMain, subStr)

print pos

10                   'A match is found at 10th char.

如果有人能告诉我如何在 Bash 中做到这一点,我将不胜感激。

答案1

我不知道有任何现有的等效产品。一些外部工具可能会提供一些开箱即用的功能,但 Bash 不会。Bash 能够做到这一点,但您需要告诉它如何做到这一点;即您需要编写一些 shell 代码。

下面的 shell 函数是此类代码的一个示例:

inStr () {
    local start string substring len pos
    start="$1"
    string="$2"
    substring="$3"

    len="${#string}"

    # strip start-1 characters
    string="${string:start-1}"

    # strip the first substring and everything beyond
    string="${string%%"$substring"*}"

    # the position is calculated
    pos=$((start+${#string}))

    # if it's more than the original length, it means "not found"
    if [ "$pos" -gt "$len" ]; then
       # not found, adjust the behavior to your needs
       # e.g. you can print -1
       return 1
    else
       printf "%s\n" "$pos"
       return 0
    fi
}

用法:

inStr 6 "abcABC123ABCabc" "AB"

笔记:

  • 在行中

    string="${string%%"$substring"*}"
    

    $substring是双引号。无论你传递什么作为子字符串,它都会按字面意思处理。例如,A*a只会匹配文字A*a。如果该行是这样的:

    string="${string%%$substring*}"
    

    然后您可以传递一个模式来匹配。在这种情况下A*a可以匹配ABCa片段。注意,在调用函数时需要引用此类子字符串,否则A*a可能会扩展为(可能是多个)匹配文件的名称(此术语包括目录) 在当前目录中(通配符)。

  • 该函数不验证其输入;特别是当使用非正起始位置时,它会产生垃圾。如果需要,请实施一些测试。
  • 边缘情况(空字符串和/或子字符串)的行为可能不符合您的预期。如果需要,请实现一些逻辑。

答案2

在纯 bash(1) 中,如何......

# Returns start position or empty string if not found - removes the
# substring + everything thereafter, thus the value of the length of the
# remaining string is the actual index of the start of the substring
instr() {
  pos = ${1/$2*}
  case ${#pos} in ${#1}) echo ;; *) echo ${#pos} ;
}

strMain="abcABC123ABCabc"
subStr="AB"        # Look for "AB".

instr "$strMain" "$subStr" # 3

答案3

PHP 中有一个类似的函数strpos(haystack, needle, pos),它已被移植到 bash 和其他 shell 中。例如,搜索“bash strpos”你就能很容易地找到它这里

然后 VB 函数就很容易实现了:

inStr() { strpos $2 $3 $1; }

strpos 中的 pos 参数是可选的。

相关内容