首页
常用运维脚本汇总
电子书阅读
Search
1
安装docker时报错container-selinux >= 2:2.74
172 阅读
2
rsync命令(可替代rm删除巨量文件)
141 阅读
3
docker 镜像加速器配置,daemon.json文件详解
133 阅读
4
使用国内镜像地址拉取k8s安装需要的images
94 阅读
5
docker search命令提示i/o timeout的解决方案
93 阅读
运维
自动化运维
数据库
容器与k8s
环境
云计算
脚本
ai
登录
Search
标签搜索
命令
nginx
zabbix
Mingrui
累计撰写
92
篇文章
累计收到
8
条评论
首页
栏目
运维
自动化运维
数据库
容器与k8s
环境
云计算
脚本
ai
页面
常用运维脚本汇总
电子书阅读
搜索到
21
篇与
的结果
2025-09-10
awk\grep\sed调优、常见错误及解决方法
性能调试# 测试命令执行时间 time grep "pattern" large_file.log # 查看命令的系统调用 strace -c grep "pattern" file.log # 监控内存使用 /usr/bin/time -v awk '{sum += $1} END {print sum}' numbers.txt内存使用优化# 避免将整个文件加载到内存 awk 'BEGIN {while ((getline line < "huge_file.log") > 0) print line}' /dev/null # 使用管道减少临时文件 grep "pattern" file.log | awk '{print $1}' | sort | uniq -c > result.txt # 分块处理大文件 split -l 100000 huge_file.log chunk_ for chunk in chunk_*; do awk '{sum += $10} END {print FILENAME, sum}' "$chunk" done | awk '{total += $2} END {print "Total:", total}'常见错误# 1. 正则表达式不匹配 # 错误示例 grep "192\.168\.1\.1" file.log # 转义过度 # 正确写法 grep "192.168.1.1" file.log # 基本正则不需要转义点号 # 2. awk字段分隔符问题 # 处理CSV文件 awk -F',' '{print $2}' data.csv # 处理多种分隔符 awk -F'[,:]' '{print $1, $3}' mixed.txt # 3. sed替换路径问题 # 错误示例 sed 's//old/path//new/path/g' file.txt # 分隔符冲突 # 正确写法 sed 's|/old/path|/new/path|g' file.txt # 使用不同分隔符高级技巧和最佳实践处理特殊字符 find . -name "*.log" -print0 | xargs -0 grep "pattern" # 处理二进制文件 grep -a "text" binary_file # 强制当作文本处理 # 处理不同编码的文件 iconv -f gbk -t utf-8 chinese.log | grep "关键词"组合命令# 复杂的日志分析流水线 tail -f access.log | \ grep --line-buffered "POST" | \ awk '{print strftime("%H:%M:%S"), $1, $7}' | \ while read time ip url; do echo "[$time] $ip 访问了 $url" done # 实时监控错误日志 tail -f error.log | \ grep --line-buffered -E "(ERROR|FATAL)" | \ sed -u 's/^/[ALERT] /' | \ tee -a alert.log脚本化和自动化analyze_nginx_log() { local logfile=$1 local pattern=${2:-""} if [ -n "$pattern" ]; then grep "$pattern" "$logfile" | awk '{print $1}' | sort | uniq -c | sort -nr else awk '{print $1}' "$logfile" | sort | uniq -c | sort -nr fi } # 使用函数 analyze_nginx_log "/var/log/nginx/access.log" "404"
2025年09月10日
3 阅读
0 评论
0 点赞
2025-09-10
实用nginx日志分析脚本
#!/bin/bash # 通用日志分析脚本 LOG_FILE=${1:-"/var/log/nginx/access.log"} TIME_RANGE=${2:-"$(date '+%d/%b/%Y')"} analyze_log() { local logfile=$1 local timerange=$2 echo "=== 分析 $logfile 中 $timerange 的数据 ===" # 基础统计 local total_requests=$(grep "$timerange" "$logfile" | wc -l) echo "总请求数: $total_requests" if [ $total_requests -eq 0 ]; then echo "没有找到匹配的日志记录" return fi # IP统计 echo "TOP 10 访问IP:" grep "$timerange" "$logfile" | \ awk '{print $1}' | \ sort | uniq -c | \ sort -nr | head -10 | \ awk '{printf "%-15s %8d 次\n", $2, $1}' # 状态码统计 echo "状态码分布:" grep "$timerange" "$logfile" | \ awk '{status[$9]++} END { for (code in status) { printf "%-5s %8d 次 (%.2f%%)\n", code, status[code], status[code]*100/NR } }' | sort -k2 -nr # 错误分析 local error_count=$(grep "$timerange" "$logfile" | grep -cE " (4[0-9]{2}|5[0-9]{2}) ") if [ $error_count -gt 0 ]; then echo "错误请求分析 (总计: $error_count):" grep "$timerange" "$logfile" | \ grep -E " (4[0-9]{2}|5[0-9]{2}) " | \ awk '{print $1, $7, $9}' | \ sort | uniq -c | \ sort -nr | head -10 | \ awk '{printf "%-15s %-30s %s (%d次)\n", $2, $3, $4, $1}' fi # 流量统计 echo "流量统计:" grep "$timerange" "$logfile" | \ awk '{ bytes += $10 if ($10 > max_bytes) { max_bytes = $10 max_url = $7 } } END { printf "总流量: %.2f MB\n", bytes/1024/1024 printf "平均请求大小: %.2f KB\n", bytes/1024/NR printf "最大请求: %s (%.2f MB)\n", max_url, max_bytes/1024/1024 }' } analyze_log "$LOG_FILE" "$TIME_RANGE"
2025年09月10日
2 阅读
0 评论
0 点赞
2025-09-09
grep/sed/awk实用案例
使用grep分析nginx日志# 统计访问最多的IP grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" access.log | sort | uniq -c | sort -nr | head -10 # 查找可疑的爬虫请求 grep -i "bot\|spider\|crawler" access.log | grep -v "Googlebot" # 分析404错误的URL grep " 404 " access.log | awk '{print $7}' | sort | uniq -c | sort -nr # 查找大文件下载请求 grep -E " [0-9]{8,} " access.log | awk '$10 > 10000000 {print $1, $7, $10}' #查找当天出现错误码400和500开头最多的访客地址 grep "$(date '+%d/%b/%Y:%H')" access.log | grep -E " (4|5)[0-9]{2} " | wc -lsed配置文件批量修改# 修改nginx配置中的端口 sed -i 's/listen 80/listen 8080/g' /etc/nginx/sites-available/* # 批量替换数据库连接配置 sed -i 's/localhost:3306/db.example.com:3306/g' /var/www/*/config/*.php # 注释掉配置文件中的某些行 sed -i '/^debug/s/^/#/' /etc/myapp/config.ini # 去掉配置文件中的注释行和空行 sed -i '/^#/d; /^$/d' config.conf #批量修改100多个配置文件的数据库地址 find /var/www -name "database.php" -exec sed -i 's/old-db-server/new-db-server/g' {} \;awk分析nginx访问日志# 统计每个IP的访问次数 awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10 # 统计状态码分布 awk '{print $9}' access.log | sort | uniq -c | sort -nr # 计算平均响应大小 awk '{sum += $10; count++} END {print "Average size:", sum/count " bytes"}' access.log # 分析访问时间分布 awk '{print substr($4, 14, 2)}' access.log | sort | uniq -c | sort -nr # 找出响应时间最长的请求(需要nginx配置记录响应时间) awk '$NF > 1.0 {print $1, $7, $NF}' access.log | sort -k3 -nr | head -10awk分析系统日志# 统计不同级别的日志数量 awk '{print $5}' /var/log/messages | sort | uniq -c # 分析内存使用情况(从free命令输出) free -m | awk 'NR==2{printf "Memory Usage: %s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }' # 分析磁盘使用情况 df -h | awk '$5 > 80 {print "Warning: " $1 " is " $5 " full"}'脚本:awk分析系统性能#!/bin/bash # 系统性能分析脚本 echo "=== CPU使用率 ===" top -bn1 | grep "Cpu(s)" | awk '{print "CPU使用率: " $2}' | sed 's/%us,//' #-b:表示批处理模式(batch mode)。在批处理模式下,top命令不会以交互式方式运行,而是直接将输出打印到标准输出(stdout)。这样便于将top的输出重定向到文件或通过管道传递给其他命令进行处理。 #-n:后面需要跟一个数字,表示top命令运行的迭代次数(iterations)。例如,-n1表示只运行一次迭代(即刷新一次)就退出。 echo "=== 内存使用情况 ===" free -m | awk 'NR==2{printf "内存使用: %s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2}' echo "=== 磁盘使用情况 ===" df -h | awk '$5+0 > 80 {print "警告: " $1 " 使用率 " $5}' echo "=== 网络连接统计 ===" ss -tuln | awk ' BEGIN {tcp=0; udp=0} /^tcp/ {tcp++} /^udp/ {udp++} END {print "TCP连接: " tcp; print "UDP连接: " udp} ' echo "=== 最占CPU的进程 ===" ps aux | awk 'NR>1 {print $11, $3}' | sort -k2 -nr | head -5分析网站攻击# 找出可疑的攻击IP grep "$(date '+%d/%b/%Y')" access.log | \ grep -E " (4[0-9]{2}|5[0-9]{2}) " | \ awk '{print $1}' | \ sort | uniq -c | \ awk '$1 > 100 {print $2, $1}' | \ sort -k2 -nr #grep筛选今天的日志 #grep找出4xx和5xx错误 #awk提取IP地址 #sort和uniq统计每个IP的错误次数 #awk筛选错误超过100次的IP #sort按错误次数排序清理日志文件# 清理30天前的日志,只保留错误信息 find /var/log -name "*.log" -mtime +30 | while read file; do grep -E "(ERROR|FATAL|Exception)" "$file" | \ sed 's/^[0-9-]* [0-9:]*//' | \ awk '!seen[$0]++' > "${file}.clean" done生成监控报告#!/bin/bash # 生成每日访问报告 LOG_FILE="/var/log/nginx/access.log" REPORT_DATE=$(date '+%d/%b/%Y') echo "=== $REPORT_DATE 访问报告 ===" echo "总访问量:" grep "$REPORT_DATE" $LOG_FILE | wc -l echo "独立IP数:" grep "$REPORT_DATE" $LOG_FILE | awk '{print $1}' | sort -u | wc -l echo "状态码分布:" grep "$REPORT_DATE" $LOG_FILE | \ awk '{print $9}' | \ sort | uniq -c | \ sort -nr | \ sed 's/^[ ]*//' | \ awk '{printf "%-10s %s\n", $2, $1}' echo "热门页面TOP10:" grep "$REPORT_DATE" $LOG_FILE | \ grep " 200 " | \ awk '{print $7}' | \ sort | uniq -c | \ sort -nr | \ head -10 | \ sed 's/^[ ]*//' | \ awk '{printf "%-50s %s\n", $2, $1}'
2025年09月09日
3 阅读
0 评论
0 点赞
2024-09-26
脚本—8:循环与判断中关于真假值的说明
有如下两例循环条件while (( COUNT < MAX )) do some stuff let COUNT++ done while [ -z "$LOCKFILE"] do some things done第一个while语句中的双括号界定了算术表达式,双括号内出现的变量名表示取值。(不需要写成$VAR的形式,直接在括号内使用VAR即可。)第二个while语句中的方括号和if语句中的用法一致,等同于使用test命令。{dotted startColor="#ff6c6c" endColor="#1989fa"/}在bash中,while语法规定该语句的条件是一系列要执行的命令(就像if语句),最后一个命令的退出状态决定了条件是真还是假。退出状态为0,表示真;否则,表示假。比如(( )),shell会对其中的表达式求值,如果结果不为0,那么(( ))就返回0;如果求值的结果为0,则返回1。比如下面这个无限循环:while ((1))do...done说明:((1))的计算结果为1,那么该表达式返回的值为0。在shell中0为真,因此这个while判断的结果永远为真,即无限循环。
2024年09月26日
78 阅读
0 评论
0 点赞
2024-09-25
脚本—7:(( ))与[[]]复合命令在if判断while循环等情况下的使用
$(()) 或者let进行整数运算说明:$(())表达式内不需要使用空格(加上也无所谓)。let命令是bash内建命令,其参数要经过单词扩展,因此最好给let的表达式加上引号。[root@web1 ~]# echo $((3+5)) 8 [root@web1 ~]# sum=200 [root@web1 ~]# echo $((3+5*sum)) 1003 [root@web1 ~]# let sum=3**5 [root@web1 ~]# echo $sum 243 {lamp/}复合命令if (( $# < 3 ))说明:双括号是复合命令的一种。这是一种比较新的bash改进,专门用于有if语句的场合。它会对其中的算术表达式求值。双括号与方括号的区别:可用于if语句的这两种语法之间的重要区别在于测试的表达方式及其能够测试的对象种类。双括号仅限于算术表达式。方括号还可以测试文件特性。但是方括号的算术测试语法远不如双括号方便,尤其是用括号将表达式分成若干子表达式时(在方括号中,需要给括号加上引号或将其转义。)例:[ ( 3 -gt 2 ) -o ( 4 -lt 1 ) ]模式匹配if [[ "${MYFILENAME}" == *.jpg ]]在if语句中使用符合命令[[]]可以在等量运算符的右侧启用shell风格的模式匹配。[[ ]] 语法不同于test命令的老形式[,它是一种较新的bash机制。能够在[]中使用的运算符也可以在[[]]中使用,但在后者中,等号是一种更为强大的字符串比较运算符。在这里面,=和==两者在语义上是相同的,但推荐使用==,这样更加醒目。标准模式匹配包括*(匹配任意数量的字符)、?(匹配单个字符)以及[](匹配字符列表中的任意一个)。注意,其写法与shell文件通配符类似,但不同于正则表达式。如果进行模式匹配,就不能把模式放入引号中,否则就只能匹配到以星号为首的字符串(模式匹配按照模式字符串的字面意义意义进行匹配)。扩展模式匹配通过启用某些bash选项,可以使用一些更为强大的模式匹配功能。shopt -s extglog #打开shell选项。extglob选项设计扩展模式匹配(或通配符匹配)。借助扩展模式匹配,我们可以使用多个模式,彼此间用|字符分割并通过括号分组。括号之前的@字符表示仅匹配括号中的模式一次。例,查找以.jpg或者.jpeg结尾的文件名shopt -s extglog if [[ "FN" == *.@(jpg|jpeg) ]] then ……扩展模式含义@( ... )仅匹配一次*( ... )匹配0次或多次+( ... )匹配1次或多次?( ... )匹配0次或1次!( ... )匹配除此之外的任何模式正则表达式匹配完整的脚本#!/usr/bin/env bash # cookbook filename: trackmatch # for CDTRACK in * do if [[ "$CDTRACK" =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]] then echo Track ${BASH_REMATCH[2]} is ${BASH_REMATCH[3]} mv "$CDTRACK" "Track${BASH_REMATCH[2]}" fi doneif [[ "$CDTRACK" =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]]说明:关于数组BASH_REMATCH,它是bash内建的数组变量。$BASH_REMATCH的各个元素由括号中的每个子表达式产生。第0个元素(${BASH_REMATCH[0]})是正则表达式所匹配的整个字符串。子表达式可以通过${BASH_REMATCH[1]},${BASH_REMATCH[2]}等形式引用。只要将正则表达式写成这样,就会生成变量$BASH_REMATCH。[:alpha:]*:这是第一个表达式,采用了POSIX字符组的[:alpha:]和[:blank:]代表任意的字母和空白字符,随后的星号表示0次或多次重复。[[:digit:]]*:这是第二个子表达式,[:digit:]代表数位,加上星号表示方括号中的数位出现0次或多次。(.*)$:匹配任意字符出现任意次数。$匹配结尾。
2024年09月25日
65 阅读
0 评论
0 点赞
1
2
3
4
5