Linux 进阶实战:数组、函数与正则表达式的高效应用指南

在 Linux 系统运维与 Shell 脚本开发中,数组、函数与正则表达式是提升脚本效率、简化复杂操作的三大核心工具。掌握它们不仅能让你摆脱重复冗余的代码,更能轻松应对日志分析、数据处理、批量任务等场景。本文将从基础概念入手,结合实战案例,带你一步步玩转这三大技术。

一、Linux 数组:让数据存储更有序

在 Shell 脚本中,数组是 “批量存储数据的容器”,支持字符串、数字等多种类型,尤其适合处理批量文件名、IP 地址、配置参数等场景。与逐个定义变量相比,数组能极大减少代码冗余,还支持灵活的增删改查操作。

1. 数组的定义与初始化

Shell 数组无需声明类型,直接通过 “键值对” 或 “列表” 形式定义,常见方式有两种:

  • 列表式定义:适合一次性存储多个元素,元素间用空格分隔

    bash

    # 定义存储服务器IP的数组
    server_ips=("192.168.1.10" "192.168.1.11" "192.168.1.12")
    # 定义存储日志文件名的数组
    log_files=("a***ess.log" "error.log" "nginx.log")
    
  • 键值对定义:适合自定义索引(如非连续数字、字符串索引)

    bash

    # 用字符串索引定义“服务-端口”映射数组
    declare -A service_ports  # 声明关联数组(支持字符串索引)
    service_ports["nginx"]=80
    service_ports["mysql"]=3306
    service_ports["redis"]=6379
    

2. 数组的核心操作(实战常用)

数组的操作重点在于 “获取元素”“遍历元素” 和 “修改元素”,以下是高频场景的实现代码:

  • 获取单个元素:通过 数组名[索引] 调用,${数组名[@]} 可获取所有元素

    bash

    echo "第一个服务器IP:${server_ips[0]}"  # 输出:192.168.1.10
    echo "所有日志文件:${log_files[@]}"     # 输出:a***ess.log error.log nginx.log
    echo "Redis端口:${service_ports["redis"]}"  # 输出:6379
    
  • 遍历数组(批量操作):结合 for 循环实现批量处理,比如批量压缩日志

    bash

    # 遍历日志文件数组,批量压缩7天前的日志
    for file in ${log_files[@]}; do
      find /var/log -name "$file" -mtime +7 -exec gzip {} \;
      echo "已压缩日志:$file"
    done
    
  • 数组长度与追加元素${#数组名[@]} 获取长度,数组名+=("新元素") 追加

    bash

    echo "服务器数量:${#server_ips[@]}"  # 输出:3
    # 追加新的服务器IP
    server_ips+=("192.168.1.13")
    echo "更新后服务器数量:${#server_ips[@]}"  # 输出:4
    

二、Linux 函数:让脚本逻辑更简洁

函数是 “封装重复代码的模块”,比如脚本中多次用到的 “日志输出”“服务状态检查” 等逻辑,都可以封装成函数。这样不仅能减少代码重复,还能让脚本结构更清晰,后期维护更方便。

1. 函数的定义与调用

Shell 函数的定义格式非常灵活,核心是 “函数名 + 代码块”,调用时直接用函数名即可:

bash

# 定义“输出带时间戳的日志”函数
log_info() {
  local timestamp=$(date "+%Y-%m-%d %H:%M:%S")  # local声明局部变量,仅函数内有效
  echo "[$timestamp] [INFO] $1"  # $1 是函数的第一个参数
}

# 定义“检查服务是否运行”函数
check_service() {
  local service_name=$1
  # 用pgrep检查进程是否存在,0为存在,非0为不存在
  if pgrep "$service_name" > /dev/null; then
    log_info "$service_name 服务正在运行"
    return 0  # 函数返回值(0表示成功)
  else
    log_info "$service_name 服务已停止"
    return 1  # 非0表示失败
  fi
}

# 调用函数
check_service "nginx"  # 输出:[2025-09-01 10:30:00] [INFO] nginx 服务正在运行
check_service "mysql"  # 输出:[2025-09-01 10:30:00] [INFO] mysql 服务正在运行

2. 函数的进阶用法(参数与返回值)

  • 函数参数:通过 $1(第一个参数)、$2(第二个参数)... $@(所有参数)获取,比如批量检查多个服务:

    bash

    # 批量检查多个服务
    batch_check() {
      for service in "$@"; do  # $@ 接收所有传入的服务名参数
        check_service "$service"
      done
    }
    
    # 调用:同时检查nginx、mysql、redis
    batch_check "nginx" "mysql" "redis"
    
  • 函数返回值:Shell 函数默认返回 “最后一条命令的退出状态”(0 成功,非 0 失败),若需返回自定义值,可通过 echo 输出,再用变量接收:

    bash

    # 定义“计算文件行数”函数
    count_lines() {
      local file_path=$1
      if [ -f "$file_path" ]; then
        wc -l "$file_path" | awk '{print $1}'  # 用awk提取行数并输出
      else
        echo 0  # 文件不存在时返回0
      fi
    }
    
    # 调用函数并接收返回值
    a***ess_lines=$(count_lines "/var/log/nginx/a***ess.log")
    echo "a***ess.log 总行数:$a***ess_lines"  # 输出:a***ess.log 总行数:12580
    

三、Linux 正则表达式:让文本处理更高效

正则表达式(简称 “正则”)是 “按规则匹配文本的工具”,在 Linux 中结合 grepsedawk 等命令,可轻松实现日志过滤、内容替换、数据提取等复杂操作。掌握正则,能让你从 “手动查找文本” 升级为 “自动化处理文本”。

1. 正则基础:常用元字符与匹配规则

正则的核心是 “元字符”(具有特殊含义的字符),以下是 Linux 中最常用的元字符及规则:

元字符 含义 示例
^ 匹配行首 ^ERROR 匹配以 “ERROR” 开头的行
$ 匹配行尾 INFO$ 匹配以 “INFO” 结尾的行
. 匹配任意单个字符 a.c 匹配 “abc”“a1c” 等
* 匹配前一个字符 0 次或多次 ab* 匹配 “a”“ab”“abb” 等
[] 匹配括号内任意一个字符 [0-9] 匹配任意数字
[^] 匹配括号外任意一个字符 [^a-z] 匹配非小写字母
\d 匹配数字(等价于 [0-9] \d{3} 匹配 3 个连续数字
\b 匹配单词边界 \buser\b 匹配独立的 “user”

2. 正则实战:结合命令解决实际问题

正则的价值在于 “结合命令使用”,以下是运维中高频的实战场景:

  • 场景 1:过滤日志中的错误信息
    用 grep 结合正则,从 nginx 错误日志中提取 “500 错误” 的行:

    bash

    # 过滤包含“500 Internal Server Error”的行,显示行号(-n)
    grep -n "500 Internal Server Error" /var/log/nginx/error.log
    # 进阶:过滤近1小时内的500错误(结合时间格式正则)
    grep -n "^$(date -d '-1 hour' +'%Y/%m/%d %H')" /var/log/nginx/error.log | grep "500"
    
  • 场景 2:批量替换配置文件内容
    用 sed 结合正则,将所有服务器配置中的 “旧 IP” 替换为 “新 IP”:

    bash

    # 替换server.conf中所有“192.168.1.10”为“192.168.1.20”(-i 表示直接修改文件)
    sed -i 's/192.168.1.10/192.168.1.20/g' /etc/server.conf
    # 进阶:替换所有以“port = ”开头的行,将端口改为8080
    sed -i 's/^port = .*/port = 8080/' /etc/app.conf
    
  • 场景 3:提取日志中的 IP 地址
    用 awk 结合正则,从 a***ess.log 中提取所有访问 IP,并统计出现次数(按次数排序):

    bash

    # 提取IP(日志中IP在第一列,用空格分隔),统计次数,按次数降序排列
    awk '{print $1}' /var/log/nginx/a***ess.log | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | sort | uniq -c | sort -nr
    # 说明:grep -E 启用扩展正则,匹配IP格式;uniq -c 统计次数;sort -nr 按数字降序
    

四、三者结合:编写高效运维脚本

单独使用数组、函数、正则已能解决很多问题,而将三者结合,能编写更强大的自动化脚本。以下是一个 “批量检查服务器服务状态” 的综合案例:

bash

#!/bin/bash
# 脚本功能:批量检查多台服务器的指定服务状态,并输出带时间戳的日志

# 1. 定义数组:存储服务器IP和需要检查的服务
server_ips=("192.168.1.10" "192.168.1.11" "192.168.1.12")
check_services=("nginx" "mysql" "redis")

# 2. 定义函数:输出带时间戳的日志
log_info() {
  local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
  echo "[$timestamp] [INFO] $1"
}

# 3. 定义函数:检查单台服务器的单个服务(通过SSH远程执行)
check_remote_service() {
  local server_ip=$1
  local service=$2
  # 用正则匹配SSH连接结果:若包含“active (running)”则服务正常
  ssh -o ConnectTimeout=5 "$server_ip" "systemctl status $service" 2>&1 | grep -qE 'active \(running\)'
  if [ $? -eq 0 ]; then
    log_info "$server_ip - $service 服务正常"
  else
    log_info "$server_ip - $service 服务异常(或SSH连接失败)"
  fi
}

# 4. 主逻辑:遍历数组,批量检查
log_info "开始批量检查服务器服务状态"
for ip in ${server_ips[@]}; do
  log_info "================ 检查服务器:$ip ================"
  for service in ${check_services[@]}; do
    check_remote_service "$ip" "$service"
  done
done
log_info "批量检查完成"

脚本执行效果如下:

plaintext

[2025-09-01 11:00:00] [INFO] 开始批量检查服务器服务状态
[2025-09-01 11:00:00] [INFO] ================ 检查服务器:192.168.1.10 ================
[2025-09-01 11:00:01] [INFO] 192.168.1.10 - nginx 服务正常
[2025-09-01 11:00:02] [INFO] 192.168.1.10 - mysql 服务正常
[2025-09-01 11:00:03] [INFO] 192.168.1.10 - redis 服务正常
[2025-09-01 11:00:03] [INFO] ================ 检查服务器:192.168.1.11 ================
[2025-09-01 11:00:08] [INFO] 192.168.1.11 - nginx 服务异常(或SSH连接失败)
...

总结

数组让数据管理更有序,函数让代码逻辑更简洁,正则让文本处理更高效 —— 这三者是 Linux 脚本开发的 “三驾马车”。从简单的批量操作,到复杂的自动化运维脚本,掌握它们能让你的工作效率大幅提升。建议从 “模仿案例” 开始,尝试将日常重复的操作(如日志清理、服务检查)写成脚本,逐步积累实战经验。如果在实践中遇到具体场景(如复杂日志提取、多维度数组处理),可以进一步深入探索进阶用法,让脚本更贴合实际需求。

转载请说明出处内容投诉
CSS教程网 » Linux 进阶实战:数组、函数与正则表达式的高效应用指南

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买