字符串操作

Shell 脚本里处理字符串是家常便饭。掌握这些操作方法,处理文本时效率翻倍。

获取字符串长度

STR="Hello World"
echo ${#STR}    # 11

# 中文也行
STR="你好世界"
echo ${#STR}    # 4

字符串拼接

A="Hello"
B="World"

# 直接拼接
C=$A$B
echo $C    # HelloWorld

# 带空格
C="$A $B"
echo $C    # Hello World

# 用花括号更清晰
C="${A}_${B}"
echo $C    # Hello_World

字符串截取

Shell 提供了多种截取方式:

按位置截取

STR="Hello World"

# 从第0个字符开始,截取5个
echo ${STR:0:5}    # Hello

# 从第6个字符开始,截取5个
echo ${STR:6:5}    # World

# 从第6个字符开始,截取到最后
echo ${STR:6}      # World

# 从倒数第5个开始截取
echo ${STR:0-5}    # World

从开头删除

STR="http://www.example.com/index.html"

# 删除最短的匹配(非贪婪)
echo ${STR#*/}     # /www.example.com/index.html

# 删除最长的匹配(贪婪)
echo ${STR##*/}    # index.html

# 实际应用:获取文件名
FILE="/path/to/file.txt"
echo ${FILE##*/}   # file.txt

从结尾删除

STR="http://www.example.com/index.html"

# 从结尾删除最短的匹配
echo ${STR%/*}     # http://www.example.com

# 从结尾删除最长的匹配
echo ${STR%%/*}    # http:

# 实际应用:获取目录
FILE="/path/to/file.txt"
echo ${FILE%/*}    # /path/to

# 获取文件扩展名
echo ${STR##*.}    # html

# 获取不带扩展名的文件名
NAME="${FILE##*/}"
echo ${NAME%.*}    # file

字符串替换

STR="hello world world"

# 替换第一个匹配
echo ${STR/world/WORLD}    # hello WORLD world

# 替换所有匹配
echo ${STR//world/WORLD}   # hello WORLD WORLD

# 替换开头的匹配
echo ${STR/#hello/HELLO}   # HELLO world world

# 替换结尾的匹配
echo ${STR/%world/WORLD}   # hello world WORLD

实际应用:

# 替换文件扩展名
FILE="document.txt"
NEW_FILE="${FILE/.txt/.pdf}"
echo $NEW_FILE    # document.pdf

# 删除所有空格
STR="hello world"
echo ${STR// /}   # helloworld

大小写转换

Bash 4.0 以上支持:

STR="Hello World"

# 转小写
echo ${STR,,}     # hello world

# 转大写
echo ${STR^^}     # HELLO WORLD

# 首字母大写
echo ${STR^}      # Hello world

旧版本可以用 tr

STR="Hello World"

# 转小写
echo $(echo $STR | tr 'A-Z' 'a-z')

# 转大写
echo $(echo $STR | tr 'a-z' 'A-Z')

字符串查找

STR="Hello World"

# 查找子串位置
expr index "$STR" "W"    # 7(从1开始)

# 判断是否包含子串
if [[ $STR == *"World"* ]]; then
    echo "包含 World"
fi

# 用正则匹配
if [[ $STR =~ World ]]; then
    echo "包含 World"
fi

字符串分割

STR="apple,banana,orange"

# 用 IFS 分割
IFS=',' read -ra ARR <<< "$STR"
for FRUIT in "${ARR[@]}"; do
    echo $FRUIT
done

# 用 cut 分割
echo $STR | cut -d',' -f1    # apple
echo $STR | cut -d',' -f2    # banana

常用技巧

判断字符串是否为空

if [ -z "$STR" ]; then
    echo "字符串为空"
fi

if [ -n "$STR" ]; then
    echo "字符串非空"
fi

去除首尾空格

STR="  hello world  "

# 去除首尾空格
STR=$(echo $STR)
echo "[$STR]"    # [hello world]

# 或用参数展开
STR="${STR#"${STR%%[![:space:]]*}"}"  # 去前导空格
STR="${STR%"${STR##*[![:space:]]}"}"  # 去尾部空格

字符串重复

# 重复字符串
STR="ab"
echo $(printf '%s' {1..5})    # 不行,用其他方法

# 用 printf 和 sed
printf 'ab%.0s' {1..5}        # ababababab

小结

字符串操作要点:

  1. 长度用 ${#STR}
  2. 截取用 ${STR:start:length}
  3. 删除用 #(开头)和 %(结尾)
  4. 替换用 ${STR/old/new}
  5. 大小写用 ,,^^