本文目录导读:

我来详细介绍Shell脚本中字符串处理的常用方法和技巧。
字符串基本操作
字符串长度
str="Hello World"
echo ${#str} # 输出:11
字符串截取
str="Hello World"
# 从位置0开始,截取5个字符
echo ${str:0:5} # Hello
# 从位置6开始到结尾
echo ${str:6} # World
# 从末尾倒数截取
echo ${str: -5} # World(注意:-前有空格)
字符串替换
str="Hello Hello World"
# 替换第一个匹配
echo ${str/Hello/Hi} # Hi Hello World
# 替换所有匹配
echo ${str//Hello/Hi} # Hi Hi World
# 替换开头匹配
echo ${str/#Hello/Hi} # Hi Hello World
# 替换结尾匹配
echo ${str/%World/Earth} # Hello Hello Earth
字符串查找和判断
查找子串位置
str="Hello World"
# 查找子串(返回位置,从1开始计数)
expr index "$str" "World" # 7
# 直接判断是否包含
if [[ "$str" == *"World"* ]]; then
echo "包含World"
fi
# 使用grep
echo "$str" | grep -o "World" # World
字符串比较
str1="Hello"
str2="World"
# 相等判断
if [ "$str1" = "$str2" ]; then
echo "相等"
fi
# 使用双方括号(推荐)
if [[ "$str1" == "$str2" ]]; then
echo "相等"
fi
# 不相等
if [[ "$str1" != "$str2" ]]; then
echo "不相等"
fi
# 大小比较
if [[ "$str1" < "$str2" ]]; then
echo "str1小于str2"
fi
字符串删除操作
str="Hello World Hello"
# 删除最短匹配(从头开始)
echo ${str#Hello} # " World Hello"
# 删除最长匹配(从头开始)
echo ${str##Hello} # " World Hello"
# 删除最短匹配(从尾开始)
echo ${str%Hello} # "Hello World "
# 删除最长匹配(从尾开始)
echo ${str%%Hello} # "Hello World "
# 删除特定模式
echo ${str#*o} # " World Hello"(删除第一个o及其之前内容)
echo ${str##*o} # " World Hello"(同上,因为只有一个o)
echo ${str%o*} # "Hello W"(删除最后一个o及其之后内容)
echo ${str%%o*} # "Hell"(删除第一个o及其之后内容)
字符串大小写转换
str="Hello World"
# 转换为大写(Bash 4+)
echo ${str^^} # HELLO WORLD
# 转换为小写(Bash 4+)
echo ${str,,} # hello world
# 首字母大写
echo ${str^} # Hello World
# 使用tr命令
echo "$str" | tr '[:lower:]' '[:upper:]' # HELLO WORLD
echo "$str" | tr '[:upper:]' '[:lower:]' # hello world
实用字符串处理函数
#!/bin/bash
# 去除首尾空格
trim() {
local var="$*"
var="${var#"${var%%[![:space:]]*}"}" # 去除开头空格
var="${var%"${var##*[![:space:]]}"}" # 去除结尾空格
echo -n "$var"
}
# 字符串分割为数组
split_string() {
local str="$1"
local delimiter="$2"
local -a arr
IFS="$delimiter" read -ra arr <<< "$str"
echo "${arr[@]}"
}
# 检查字符串是否以特定前缀开头
starts_with() {
local str="$1"
local prefix="$2"
[[ "$str" == "$prefix"* ]]
}
# 检查字符串是否以特定后缀结尾
ends_with() {
local str="$1"
local suffix="$2"
[[ "$str" == *"$suffix" ]]
}
# 使用示例
text=" Hello World "
echo "原始: '$text'"
trimmed=$(trim "$text")
echo "修剪后: '$trimmed'"
# 字符串分割
result=$(split_string "apple,banana,orange" ",")
echo "分割结果: $result"
# 前缀后缀检查
if starts_with "$text" " Hello"; then
echo "以' Hello'开头"
fi
高级字符串处理
# 字符串长度控制
str="Hello World"
# 截取前5个字符
echo "${str:0:5}"
# 从第6个字符到结尾
echo "${str:5}"
# 如果字符串长度大于10,截取前10个
echo "${str:0:10}"
# Pad字符串到指定长度
pad_string() {
local str="$1"
local length="$2"
local pad_char="${3:- }"
while [ ${#str} -lt $length ]; do
str="$str$pad_char"
done
echo "$str"
}
# 使用sed进行复杂替换
echo "Hello123World456" | sed 's/[0-9]//g' # HelloWorld
echo "hello world" | sed 's/\b\(.\)/\u\1/g' # Hello World(首字母大写)
# 使用awk处理字符串
echo "192.168.1.1" | awk -F. '{print $1"."$2"."$3}' # 192.168.1
实际应用示例
#!/bin/bash
# 文件路径处理
filepath="/home/user/documents/file.txt"
# 获取文件名
filename=$(basename "$filepath")
echo "文件名: $filename" # file.txt
# 获取目录路径
dirname=$(dirname "$filepath")
echo "目录: $dirname" # /home/user/documents
# 获取文件扩展名
extension="${filepath##*.}"
echo "扩展名: $extension" # txt
# 获取文件名(不含扩展名)
basename="${filename%.*}"
echo "文件名(不含扩展名): $basename" # file
# CSV解析
csv_line="name,age,city"
IFS=',' read -r name age city <<< "$csv_line"
echo "姓名: $name, 年龄: $age, 城市: $city"
Shell字符串处理的核心操作:
- 截取:
${str:start:length} - 替换:
${str/old/new}和${str//old/new} - 删除:
${str#pattern}和${str%pattern} - 查找: 使用
expr index或grep - 大小写:
${str^^}和${str,,} - 长度:
${#str}
这些操作通常比使用外部命令(如sed、awk)效率更高,建议优先使用。