Shell脚本如何实现字符串处理

wen 实用脚本 1

本文目录导读:

Shell脚本如何实现字符串处理

  1. 字符串基本操作
  2. 字符串查找和判断
  3. 字符串删除操作
  4. 字符串大小写转换
  5. 实用字符串处理函数
  6. 高级字符串处理
  7. 实际应用示例

我来详细介绍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 indexgrep
  • 大小写: ${str^^}${str,,}
  • 长度: ${#str}

这些操作通常比使用外部命令(如sed、awk)效率更高,建议优先使用。

抱歉,评论功能暂时关闭!