第167集:字符串处理

教学目标

  • 掌握Shell脚本中字符串的基本操作方法
  • 学习字符串的比较和测试
  • 理解字符串的查找和替换操作
  • 掌握字符串的格式化和拼接
  • 学习字符串的转换和处理技巧
  • 能够在脚本中灵活处理各种字符串操作

主要知识点

  1. 字符串的基本操作
  2. 字符串的长度计算
  3. 字符串的拼接
  4. 字符串的截取
  5. 字符串的比较
  6. 字符串的查找和替换
  7. 字符串的格式化
  8. 字符串的转换
  9. 字符串的分割和连接

实用案例分析

案例1:字符串基本操作

目标:学习Shell脚本中字符串的基本操作。

操作步骤

  1. 创建字符串基本操作演示脚本
# 创建脚本文件
touch string-basics.sh

# 编辑脚本文件
vim string-basics.sh

# 添加以下内容
#!/bin/bash
# 演示字符串基本操作

# 1. 定义字符串
str1="Hello"
str2='World'
str3="Linux Operating System"

# 2. 计算字符串长度
echo "=== Calculating string length ==="
echo "Length of str1: ${#str1}"
echo "Length of str2: ${#str2}"
echo "Length of str3: ${#str3}"

# 3. 字符串拼接
echo "\n=== String concatenation ==="
# 方法1:直接连接
combined1="$str1 $str2"
echo "Combined 1: $combined1"

# 方法2:使用+号(注意:Bash中+不是字符串连接符)
combined2=$str1" "$str2
echo "Combined 2: $combined2"

# 方法3:使用变量展开
combined3=${str1} ${str2}
echo "Combined 3: $combined3"

# 4. 字符串截取
echo "\n=== String slicing ==="
# 从索引0开始,取5个字符
slice1=${str3:0:5}
echo "First 5 characters: $slice1"

# 从索引6开始,取9个字符
slice2=${str3:6:9}
echo "Characters from index 6: $slice2"

# 从索引16开始,取到末尾
slice3=${str3:16}
echo "Characters from index 16 to end: $slice3"

# 从末尾开始取5个字符
slice4=${str3: -5}
echo "Last 5 characters: $slice4"

# 5. 字符串变量展开
echo "\n=== Variable expansion ==="
# 变量替换
name="Alice"
echo "Hello, ${name}!"

# 变量默认值
unset var
echo "Default value: ${var:-'No value'}"

# 变量赋值默认值
var=${var:-'New value'}
echo "After assignment: $var"

# 变量存在性检查
echo "Variable exists: ${var:+'Yes'}"
  1. 运行脚本并查看结果
# 设置执行权限
chmod +x string-basics.sh

# 运行脚本
./string-basics.sh

案例2:字符串比较

目标:学习在Shell脚本中比较字符串。

操作步骤

  1. 创建字符串比较演示脚本
# 创建脚本文件
touch string-comparison.sh

# 编辑脚本文件
vim string-comparison.sh

# 添加以下内容
#!/bin/bash
# 演示字符串比较

# 定义测试字符串
str1="apple"
str2="banana"
str3="apple"

# 1. 使用test命令比较
echo "=== Using test command ==="
if test "$str1" = "$str3"; then
    echo "str1 equals str3"
fi

if test "$str1" != "$str2"; then
    echo "str1 not equals str2"
fi

# 2. 使用[ ]比较
echo "\n=== Using [ ] ==="
if [ "$str1" = "$str3" ]; then
    echo "str1 equals str3"
fi

if [ "$str1" != "$str2" ]; then
    echo "str1 not equals str2"
fi

# 3. 使用[[ ]]比较(支持通配符)
echo "\n=== Using [[ ]] ==="
if [[ "$str1" == "a*" ]]; then
    echo "str1 starts with 'a'"
fi

if [[ "$str2" == *"na" ]]; then
    echo "str2 ends with 'na'"
fi

if [[ "$str3" == *"ppl"* ]]; then
    echo "str3 contains 'ppl'"
fi

# 4. 字符串大小比较(字典序)
echo "\n=== Lexicographical comparison ==="
if [[ "$str1" < "$str2" ]]; then
    echo "str1 comes before str2"
fi

if [[ "$str2" > "$str3" ]]; then
    echo "str2 comes after str3"
fi

# 5. 检查字符串是否为空
echo "\n=== Checking for empty strings ==="
empty_str=""
unset unset_str

if [ -z "$empty_str" ]; then
    echo "empty_str is empty"
fi

if [ -n "$str1" ]; then
    echo "str1 is not empty"
fi

if [ -z "$unset_str" ]; then
    echo "unset_str is empty"
fi
  1. 运行脚本并查看结果
# 设置执行权限
chmod +x string-comparison.sh

# 运行脚本
./string-comparison.sh

案例3:字符串查找和替换

目标:学习在Shell脚本中查找和替换字符串。

操作步骤

  1. 创建字符串查找和替换演示脚本
# 创建脚本文件
touch string-search-replace.sh

# 编辑脚本文件
vim string-search-replace.sh

# 添加以下内容
#!/bin/bash
# 演示字符串查找和替换

# 定义测试字符串
str="Hello Linux World! Linux is great."

# 1. 查找子字符串
echo "=== Searching for substrings ==="
# 使用grep查找
if echo "$str" | grep -q "Linux"; then
    echo "'Linux' found in string"
fi

# 使用[[ ]]查找
if [[ "$str" == *"World"* ]]; then
    echo "'World' found in string"
fi

# 2. 替换子字符串
echo "\n=== Replacing substrings ==="
# 替换第一个匹配项
replaced1=${str/Linux/Unix}
echo "Replace first 'Linux': $replaced1"

# 替换所有匹配项
replaced2=${str//Linux/Unix}
echo "Replace all 'Linux': $replaced2"

# 替换开头的匹配项
replaced3=${str/#Hello/Hi}
echo "Replace 'Hello' at start: $replaced3"

# 替换结尾的匹配项
replaced4=${str/%great./awesome!}
echo "Replace 'great.' at end: $replaced4"

# 3. 使用sed命令替换
echo "\n=== Using sed for replacement ==="
# 替换所有匹配项
sed_replaced=$(echo "$str" | sed 's/Linux/Unix/g')
echo "sed replace all: $sed_replaced"

# 替换第2个匹配项
sed_replaced2=$(echo "$str" | sed 's/Linux/Unix/2')
echo "sed replace second occurrence: $sed_replaced2"

# 4. 查找子字符串位置
echo "\n=== Finding substring position ==="
# 使用awk查找
pos=$(echo "$str" | awk -F'Linux' '{print length($1)}')
echo "Position of first 'Linux': $pos"

# 5. 提取子字符串
echo "\n=== Extracting substrings ==="
# 提取第一个单词
first_word=$(echo "$str" | cut -d' ' -f1)
echo "First word: $first_word"

# 提取从第7个字符开始的字符串
extracted=${str:6}
echo "Extracted from index 6: $extracted"
  1. 运行脚本并查看结果
# 设置执行权限
chmod +x string-search-replace.sh

# 运行脚本
./string-search-replace.sh

案例4:字符串格式化和转换

目标:学习在Shell脚本中格式化和转换字符串。

操作步骤

  1. 创建字符串格式化和转换演示脚本
# 创建脚本文件
touch string-formatting.sh

# 编辑脚本文件
vim string-formatting.sh

# 添加以下内容
#!/bin/bash
# 演示字符串格式化和转换

# 1. 字符串大小写转换
echo "=== Case conversion ==="
str="Hello Linux World"
echo "Original: $str"

# 转换为大写
upper=$(echo "$str" | tr '[:lower:]' '[:upper:]')
echo "Uppercase: $upper"

# 转换为小写
lower=$(echo "$str" | tr '[:upper:]' '[:lower:]')
echo "Lowercase: $lower"

# 首字母大写(简单实现)
title=$(echo "$str" | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2));}1')
echo "Title case: $title"

# 2. 字符串格式化
echo "\n=== String formatting ==="
# 使用printf格式化
name="Alice"
age=30
salary=50000

printf "Name: %s\n" "$name"
printf "Age: %d\n" "$age"
printf "Salary: $%.2f\n" "$salary"
printf "%-10s %5d %10.2f\n" "$name" "$age" "$salary"

# 3. 字符串填充和对齐
echo "\n=== String padding and alignment ==="
# 左对齐,宽度为20
printf "%-20s|\n" "Left aligned"

# 右对齐,宽度为20
printf "%20s|\n" "Right aligned"

# 居中对齐(简单实现)
center() {
    local str=$1
    local width=$2
    local padding=$(( (width - ${#str}) / 2 ))
    printf "%*s%s%*s\n" $padding "" "$str" $padding ""
}

center "Centered" 20

# 4. 数字格式化
echo "\n=== Number formatting ==="
number=1234567.89

# 千位分隔符
formatted=$(echo "$number" | awk '{printf "%\047d\n", $1}')
echo "With thousands separator: $formatted"

# 固定小数位数
formatted2=$(printf "%.2f" "$number")
echo "Two decimal places: $formatted2"

# 科学计数法
formatted3=$(printf "%e" "$number")
echo "Scientific notation: $formatted3"

# 5. 特殊字符处理
echo "\n=== Special character handling ==="
special_str="Line1\nLine2\tTabbed"
echo "With special characters:"
echo -e "$special_str"

# 转义特殊字符
escaped=$(printf "%q" "$special_str")
echo "\nEscaped: $escaped"
  1. 运行脚本并查看结果
# 设置执行权限
chmod +x string-formatting.sh

# 运行脚本
./string-formatting.sh

案例5:字符串分割和连接

目标:学习在Shell脚本中分割和连接字符串。

操作步骤

  1. 创建字符串分割和连接演示脚本
# 创建脚本文件
touch string-split-join.sh

# 编辑脚本文件
vim string-split-join.sh

# 添加以下内容
#!/bin/bash
# 演示字符串分割和连接

# 1. 字符串分割
echo "=== String splitting ==="
# 使用IFS分割
str="apple,banana,cherry,date"
IFS="," read -ra fruits <<< "$str"
echo "Split by comma:"
for fruit in "${fruits[@]}"; do
    echo "- $fruit"
done

# 使用awk分割
str2="Alice:25:Female"
echo "\nSplit by colon using awk:"
echo "$str2" | awk -F":" '{print "Name: " $1, "Age: " $2, "Gender: " $3}'

# 使用cut分割
echo "\nSplit by colon using cut:"
echo "$str2" | cut -d":" -f1
echo "$str2" | cut -d":" -f2
echo "$str2" | cut -d":" -f3

# 2. 字符串连接
echo "\n=== String joining ==="
# 数组元素连接
fruits_array=(apple banana cherry date)
joined=$(IFS=","; echo "${fruits_array[*]}")
echo "Joined with comma: $joined"

# 使用printf连接
joined2=$(printf "%s|" "${fruits_array[@]}")
# 移除末尾的分隔符
joined2=${joined2%|}
echo "Joined with pipe: $joined2"

# 3. 多行文本处理
echo "\n=== Multi-line text processing ==="
multi_line="Line 1\nLine 2\nLine 3\nLine 4"
echo "Original multi-line text:"
echo -e "$multi_line"

# 分割成数组
IFS=$'\n' read -ra lines <<< "$multi_line"
echo "\nSplit into array:"
for i in "${!lines[@]}"; do
    echo "Line $i: ${lines[$i]}"
done

# 4. 实际应用:解析CSV数据
echo "\n=== Parsing CSV data ==="
# 模拟CSV数据
csv_data="Name,Age,City\nAlice,25,New York\nBob,30,London\nCharlie,35,Paris"

echo "CSV data:"
echo -e "$csv_data"

echo "\nParsed CSV:"
IFS=$'\n' read -ra rows <<< "$csv_data"
for i in "${!rows[@]}"; do
    if [ $i -eq 0 ]; then
        # 表头
        IFS="," read -ra headers <<< "${rows[$i]}"
        echo "Headers: ${headers[@]}"
    else
        # 数据行
        IFS="," read -ra fields <<< "${rows[$i]}"
        echo "Row $i:"
        for j in "${!fields[@]}"; do
            echo "  ${headers[$j]}: ${fields[$j]}"
        done
    fi
done
  1. 运行脚本并查看结果
# 设置执行权限
chmod +x string-split-join.sh

# 运行脚本
./string-split-join.sh

案例6:高级字符串处理技巧

目标:学习一些高级的字符串处理技巧。

操作步骤

  1. 创建高级字符串处理演示脚本
# 创建脚本文件
touch advanced-string.sh

# 编辑脚本文件
vim advanced-string.sh

# 添加以下内容
#!/bin/bash
# 演示高级字符串处理技巧

# 1. 正则表达式匹配
echo "=== Regular expression matching ==="
email="user@example.com"
phone="123-456-7890"

if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
    echo "Valid email: $email"
else
    echo "Invalid email: $email"
fi

if [[ "$phone" =~ ^[0-9]{3}-[0-9]{3}-[0-9]{4}$ ]]; then
    echo "Valid phone: $phone"
else
    echo "Invalid phone: $phone"
fi

# 2. 字符串替换和转换
echo "\n=== Advanced string replacement ==="
# 驼峰命名转换为下划线命名
camel_case="firstName lastName"
underscore=$(echo "$camel_case" | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\2/g' | tr '[:upper:]' '[:lower:]')
echo "Camel case: $camel_case"
echo "Underscore: $underscore"

# 3. 字符串去重
echo "\n=== String deduplication ==="
duplicate_str="aaabbbcccdddeee"
deduplicated=$(echo "$duplicate_str" | sed 's/\(\(.)\)\1*/\1/g')
echo "Original: $duplicate_str"
echo "Deduplicated: $deduplicated"

# 4. 字符串反转
echo "\n=== String reversal ==="
original="Hello World"
reversed=$(echo "$original" | rev)
echo "Original: $original"
echo "Reversed: $reversed"

# 5. 单词统计
echo "\n=== Word counting ==="
text="The quick brown fox jumps over the lazy dog"
word_count=$(echo "$text" | wc -w)
echo "Text: $text"
echo "Word count: $word_count"

# 字符统计
char_count=$(echo -n "$text" | wc -c)
echo "Character count: $char_count"

# 行数统计
line_count=$(echo -e "$text\nAnother line" | wc -l)
echo "Line count: $line_count"

# 6. 字符串加密和解密(简单实现)
echo "\n=== Simple string encryption/decryption ==="
# 简单的凯撒密码
encrypt() {
    local str=$1
    local shift=$2
    echo "$str" | tr "[a-z]" "[$((shift + 97))-z[a-${((shift + 96))]]" | tr "[A-Z]" "[$((shift + 65))-Z[A-${((shift + 64))]]"
}

decrypt() {
    local str=$1
    local shift=$2
    encrypt "$str" $((26 - shift))
}

secret="Hello Linux"
encrypted=$(encrypt "$secret" 3)
echo "Original: $secret"
echo "Encrypted: $encrypted"

decrypted=$(decrypt "$encrypted" 3)
echo "Decrypted: $decrypted"

# 7. URL编码和解码
echo "\n=== URL encoding/decoding ==="
url="https://example.com/path with spaces?query=value"

# URL编码
encoded=$(printf '%s' "$url" | sed 's/ /%20/g; s/!/%21/g; s/"/%22/g; s/#/%23/g; s/\$/%24/g; s/&/%26/g; s/'"'"'/%27/g; s/(/%28/g; s/)/%29/g; s/\*/%2A/g; s/+/%2B/g; s/,/%2C/g; s/;/%3B/g; s/=/%3D/g; s/?/%3F/g; s/@/%40/g')
echo "Original URL: $url"
echo "Encoded URL: $encoded"

# 8. 模板替换
echo "\n=== Template replacement ==="
template="Hello {name}, you are {age} years old and live in {city}."

# 替换函数
replace_template() {
    local template=$1
    local name=$2
    local age=$3
    local city=$4
    
    template=${template/{name}/$name}
    template=${template/{age}/$age}
    template=${template/{city}/$city}
    
    echo "$template"
}

replace_template "$template" "Alice" "25" "New York"
replace_template "$template" "Bob" "30" "London"
  1. 运行脚本并查看结果
# 设置执行权限
chmod +x advanced-string.sh

# 运行脚本
./advanced-string.sh

课后练习

  1. 基础练习

    • 创建一个脚本,计算字符串中单词的数量
    • 编写一个脚本,将字符串转换为大写并反转
    • 设计一个脚本,检查字符串是否是回文
  2. 进阶练习

    • 创建一个脚本,解析日志文件中的IP地址
    • 编写一个脚本,格式化电话号码为标准格式
    • 设计一个脚本,从CSV文件中提取特定列的数据
  3. 挑战练习

    • 编写一个脚本,实现简单的文本搜索引擎
    • 创建一个脚本,解析和处理JSON格式的字符串
    • 设计一个脚本,实现字符串的压缩和解压缩

总结

本集详细介绍了Linux Shell脚本中的字符串处理操作,包括字符串的基本操作、比较、查找替换、格式化、转换、分割和连接等内容。通过学习这些知识,读者可以在Shell脚本中灵活处理各种字符串操作,提高脚本的实用性和效率。

字符串处理是Shell脚本编程中的重要组成部分,它允许脚本处理和分析文本数据,实现各种文本操作和转换。掌握字符串处理技巧是编写复杂Shell脚本的基础。

通过本集的学习,读者应该能够理解和使用基本的字符串操作,掌握字符串的比较和测试方法,理解字符串的查找和替换操作,掌握字符串的格式化和拼接技巧,以及学习字符串的转换和处理方法。这些知识将为后续学习文件操作和错误处理打下基础。

« 上一篇 数组操作 下一篇 » 文件操作