概述
Shell脚本中的字符串操作是日常运维和自动化必备技能。
获取字符串长度
基本方法
# 使用 ${#VAR}
VAR="hello"
echo ${#VAR}
# 输出: 5
# 变量也可以直接
echo ${#"hello"}
# 输出: 5
不同Shell中的方法
# Bash
VAR="hello"
echo ${#VAR} # 5
echo ${#VAR[0]} # 数组
# expr 命令
VAR="hello"
expr length "$VAR"
# 输出: 5
# wc 命令
VAR="hello"
echo -n "$VAR" | wc -c
# 输出: 5
# awk
VAR="hello"
echo "$VAR" | awk '{print length}'
# 输出: 5
字符串截取
1. 从左边开始截取
VAR="Hello World"
# ${VAR:start} - 从第start个字符截取到结尾(从0开始)
echo ${VAR:1}
# 输出: ello World
# ${VAR:start:length} - 截取从start开始,长度为length的字符
echo ${VAR:0:5}
# 输出: Hello
# ${VAR: -length} - 从右边截取length个字符(注意冒号后有空格)
echo ${VAR: -5}
# 输出: World
2. 使用expr命令
VAR="Hello World"
# expr substr $VAR start length
expr substr "$VAR" 1 5
# 输出: Hello
# start从1开始
3. 使用cut命令
VAR="Hello World"
# 截取前5个字符
echo "$VAR" | cut -c1-5
# 输出: Hello
# 截取第7个字符到最后
echo "$VAR" | cut -c7-
# 输出: World
字符串替换
1. 替换第一个匹配
VAR="Hello World World"
# ${VAR/pattern/replacement}
echo ${VAR/World/Shell}
# 输出: Hello Shell World
2. 替换所有匹配
VAR="Hello World World"
# ${VAR//pattern/replacement}
echo ${VAR//World/Shell}
# 输出: Hello Shell Shell
3. 替换开头或结尾
VAR="Hello World"
# 替换开头的匹配
echo ${VAR/#Hello/Hi}
# 输出: Hi World
# 替换结尾的匹配
echo ${VAR/%World/Earth}
# 输出: Hello Earth
4. 删除匹配
VAR="Hello World"
# 删除第一个匹配
echo ${VAR/World}
# 输出: Hello
# 删除所有匹配
echo ${VAR//World}
# 输出: Hello
# 删除开头匹配
echo ${VAR/#Hello}
# 输出: World
# 删除结尾匹配
echo ${VAR/%World}
# 输出: Hello
模式匹配
1. 提取子串
VAR="/path/to/file.txt"
# 删除最小的前缀匹配
echo ${VAR##*/}
# 输出: file.txt
# 删除最大的前缀匹配(##贪婪匹配)
echo ${VAR##*/}
# 输出: file.txt
# 删除最小的后缀匹配
echo ${VAR%.*}
# 输出: /path/to/file
# 删除最大的后缀匹配
echo ${VAR%%.*}
# 输出: /path/to
2. 实际应用
# 获取文件名
FILE="/var/log/nginx/access.log"
echo ${FILE##*/}
# 输出: access.log
# 获取目录
FILE="/var/log/nginx/access.log"
echo ${FILE%/*}
# 输出: /var/log/nginx
# 获取扩展名
FILE="document.pdf"
echo ${FILE##*.}
# 输出: pdf
# 去除扩展名
FILE="document.pdf"
echo ${FILE%.*}
# 输出: document
字符串比较
# 判断是否为空
VAR=""
if [ -z "$VAR" ]; then
echo "VAR is empty"
fi
# 判断是否非空
VAR="hello"
if [ -n "$VAR" ]; then
echo "VAR is not empty"
fi
# 判断是否相等
VAR1="hello"
VAR2="hello"
if [ "$VAR1" = "$VAR2" ]; then
echo "equal"
fi
字符串大小写转换
VAR="Hello World"
# 转换为大写
echo ${VAR^^}
# 输出: HELLO WORLD
# 转换为小写
echo ${VAR,,}
# 输出: hello world
字符串连接
# 直接连接
VAR1="Hello"
VAR2="World"
VAR3="$VAR1 $VAR2"
echo $VAR3
# 输出: Hello World
实用脚本示例
1. 批量重命名文件
# 去除文件名中的空格
for file in *\ *; do
mv "$file" ${file// /_}
done
2. 提取URL中的域名
URL="https://www.example.com/path/to/page"
# 方法1:删除协议和路径
DOMAIN=${URL#*://}
DOMAIN=${DOMAIN%%/*}
echo $DOMAIN
# 输出: www.example.com
3. 格式化日期
DATE=$(date +%Y%m%d)
FILENAME="backup_$DATE.tar.gz"
echo $FILENAME
# 输出: backup_20260314.tar.gz
4. 检查字符串是否包含子串
VAR="Hello World"
if [[ "$VAR" == *"World"* ]]; then
echo "包含 World"
fi
常用操作速查表
| 操作 | 语法 |
|---|---|
| 长度 | ${#VAR} |
| 截取 | ${VAR:start:len} |
| 替换 | ${VAR/old/new} |
| 删除前缀 | ${VAR#pattern} |
| 删除后缀 | ${VAR%pattern} |
| 大写 | ${VAR^^} |
| 小写 | ${VAR,,} |
Comments