我是 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 参数是可选的。