Skip to content

字符串处理

Shell 提供了多种字符串处理方式,包括内置参数扩展和外部命令。

字符串长度

bash
str="Hello World"
echo ${#str}                     # 11
echo $(echo -n "$str" | wc -c)  # 11

字符串拼接

bash
first="Hello"
second="World"

# 直接拼接
result="${first} ${second}"
echo $result   # Hello World

# 拼接追加
str="Hello"
str+=" World"
echo $str      # Hello World

子字符串截取

bash
str="Hello World"

# ${str:start:length}
echo ${str:0:5}    # Hello
echo ${str:6}      # World
echo ${str: -5}    # World(从末尾数)
echo ${str: -5:3}  # Wor

查找与替换

bash
str="I love shell and shell is great"

# 替换第一个匹配
echo ${str/shell/bash}    # I love bash and shell is great

# 替换所有匹配
echo ${str//shell/bash}   # I love bash and bash is great

# 删除匹配(替换为空)
echo ${str// /}           # IloveshellandshellIsgreat(删除所有空格)

大小写转换

bash
str="Hello World"

echo ${str,,}   # hello world(全小写,Bash 4+)
echo ${str^^}   # HELLO WORLD(全大写,Bash 4+)

# 兼容旧版本的方式
echo "$str" | tr 'A-Z' 'a-z'   # 转小写
echo "$str" | tr 'a-z' 'A-Z'   # 转大写

前后缀操作

bash
str="Hello World"

# 去除前缀
echo ${str#Hello }    # World

# 去除后缀
echo ${str% World}    # Hello

# 检测前缀
[[ "$str" == Hello* ]] && echo "以 Hello 开头"

# 检测后缀
[[ "$str" == *World ]] && echo "以 World 结尾"

字符串分割

bash
# 使用 IFS 分割
str="a:b:c:d"
IFS=':' read -ra parts <<< "$str"
for part in "${parts[@]}"; do
    echo "$part"
done

# 使用 cut 分割
echo "a:b:c" | cut -d: -f2   # b

# 使用 awk 分割
echo "a:b:c" | awk -F: '{print $2}'   # b

字符串包含判断

bash
str="Hello World"

# 方式一:[[ ]]
if [[ "$str" == *"World"* ]]; then
    echo "包含 World"
fi

# 方式二:grep
if echo "$str" | grep -q "World"; then
    echo "包含 World"
fi

# 方式三:参数扩展(去掉匹配看长度变化)
if [ "${str/World/}" != "$str" ]; then
    echo "包含 World"
fi

去除首尾空格

bash
str="  hello world  "

# 使用参数扩展(Bash 4.2+)
# 去除前导空格
trimmed="${str#"${str%%[![:space:]]*}"}"
# 去除尾部空格
trimmed="${trimmed%"${trimmed##*[![:space:]]}"}"
echo "'$trimmed'"   # 'hello world'

# 更简单:使用 sed
trimmed=$(echo "$str" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

# 使用 xargs(最简单)
trimmed=$(echo "$str" | xargs)
echo "'$trimmed'"   # 'hello world'

字符串反转

bash
str="hello"
echo "$str" | rev   # olleh

重复字符串

bash
# printf 方式
printf '=%.0s' {1..20}   # 输出 20 个 =
echo

# 循环方式
str=""
for ((i=0; i<5; i++)); do
    str+="ha"
done
echo $str   # hahahahaha

实用函数

bash
#!/bin/bash

# 字符串是否为数字
is_number() {
    [[ "$1" =~ ^[0-9]+$ ]]
}

# 字符串是否为空或只有空格
is_blank() {
    [[ -z "${1// /}" ]]
}

# 首字母大写
capitalize() {
    local str="$1"
    echo "${str^}"
}

# 统计子字符串出现次数
count_substr() {
    local str="$1"
    local sub="$2"
    local temp="${str//$sub/}"
    echo $(( (${#str} - ${#temp}) / ${#sub} ))
}

# 测试
is_number "123" && echo "123 是数字"
is_number "abc" || echo "abc 不是数字"
is_blank "   " && echo "只有空格"
capitalize "hello"        # Hello
count_substr "banana" "an"   # 2