进阶——写成自动化脚本实现日志文件的定位

生产大批量日志场景中,根据关键字快速定位-CSDN博客

        如果日志很多,又需要针对某个目录下面的日志文件,进行关键字定位,并过滤不包含某些关键字的日志文件,初步定位一部分符合的日志文件,以便后续针对符合的日志文件,人工介入做详细分析。


 

脚本原文

#!/bin/bash
# 文件名:smart_grep.sh
# 用法:./smart_grep.sh [目录] [包含关键字] [排除关键字]
# 示例:./smart_grep.sh /var/log "error timeout" "ignore skip"

# 检查参数数量
if [ $# -lt 2 ]; then
    echo "错误:参数不足"
    echo "用法: $0 [目录] \"包含关键字1 包含关键字2...\" \"[排除关键字1 排除关键字2...]\""
    exit 1
fi

# 设置参数
SEARCH_DIR="${1}"
INCLUDE_KEYS="${2}"
EXCLUDE_KEYS="${3}"

# 创建临时文件
TMP_FILE_LIST=$(mktemp)
TMP_FINAL_LIST=$(mktemp)

# 清理函数
cleanup() {
    rm -f "$TMP_FILE_LIST" "$TMP_FINAL_LIST"
    exit
}
trap cleanup EXIT INT TERM

echo "步骤1: 定位包含所有关键字的文件..."
# 第一步:定位包含所有关键字的文件
IFS=' ' read -ra KEYS <<< "$INCLUDE_KEYS"
FIRST_KEY="${KEYS[0]}"
OTHER_KEYS=("${KEYS[@]:1}")

# 初始搜索
grep -rlZ -- "$FIRST_KEY" "$SEARCH_DIR" > "$TMP_FILE_LIST"

# 处理其他关键字
for key in "${OTHER_KEYS[@]}"; do
    if [ -s "$TMP_FILE_LIST" ]; then
        xargs -0 -a "$TMP_FILE_LIST" grep -rlZ -- "$key" > "$TMP_FINAL_LIST"
        mv "$TMP_FINAL_LIST" "$TMP_FILE_LIST"
    else
        echo "未找到包含所有关键字的文件"
        exit 0
    fi
done

# 检查是否有文件
if [ ! -s "$TMP_FILE_LIST" ]; then
    echo "未找到包含所有关键字的文件"
    exit 0
fi

FILE_COUNT=$(tr -cd '\0' < "$TMP_FILE_LIST" | wc -c)
echo "找到 $FILE_COUNT 个包含所有关键字的文件"

echo "步骤2: 过滤排除关键字..."
# 第二步:过滤排除关键字
if [ -n "$EXCLUDE_KEYS" ]; then
    IFS=' ' read -ra EXC_KEYS <<< "$EXCLUDE_KEYS"
    for exc_key in "${EXC_KEYS[@]}"; do
        if [ -s "$TMP_FILE_LIST" ]; then
            # 使用grep -v过滤包含排除关键字的文件
            xargs -0 -a "$TMP_FILE_LIST" grep -rlZ -- "$exc_key" | 
                xargs -0 -I{} sh -c 'grep -vZF "{}" "$TMP_FILE_LIST" > "$TMP_FINAL_LIST"; mv "$TMP_FINAL_LIST" "$TMP_FILE_LIST"'
        fi
    done
fi

# 输出最终结果
FINAL_COUNT=$(tr -cd '\0' < "$TMP_FILE_LIST" | wc -c)
if [ "$FINAL_COUNT" -gt 0 ]; then
    echo -e "\n最终匹配的文件 ($FINAL_COUNT 个):"
    # 使用tr替换空字符为换行以便阅读
    tr '\0' '\n' < "$TMP_FILE_LIST"
else
    echo "没有找到符合条件的文件"
fi

脚本功能说明

  1. 参数处理

    • 第一个参数:搜索目录(必需)

    • 第二个参数:包含关键字(空格分隔的多个关键字,必需)

    • 第三个参数:排除关键字(空格分隔的多个关键字,可选)

  2. 处理流程

    • 步骤1:递归查找包含所有指定关键字的文件

    • 步骤2:从结果中排除包含任何排除关键字的文件

    • 输出:最终符合条件的文件名列表

  3. 技术亮点

    • 使用 -Z 和 xargs -0 处理含空格/特殊字符的文件名

    • 分阶段处理减少内存消耗

    • 实时显示各阶段找到的文件数量

    • 安全的临时文件处理(使用 trap 确保清理)

使用示例

# 基本用法
./smart_grep.sh /var/log "error timeout"

# 包含多个关键字并排除多个关键字
./smart_grep.sh /app/logs "payment transaction" "failed test"

# 在代码库中搜索(排除测试文件)
./smart_grep.sh ~/projects "config database" "mock test debug"

输出示例

步骤1: 定位包含所有关键字的文件...
找到 42 个包含所有关键字的文件
步骤2: 过滤排除关键字...

最终匹配的文件 (18 个):
/var/log/app/payment_20231020.log
/var/log/db/transaction_20231021.log
/var/log/api/process_20231022.log

注意事项

  1. 性能优化

    • 大目录搜索时添加 --include=*.log 限制文件类型

    • 使用 --exclude-dir={cache,tmp} 排除目录

    • 超大文件集考虑添加 --max-depth=3 限制搜索深度

  2. 高级用法

    # 仅搜索 .py 文件并排除 test 目录
    ./smart_grep.sh ~/project \
        "import module" \
        "test mock" \
        --include="*.py" \
        --exclude-dir=test
  3. 兼容性

    • 支持所有现代 Linux 发行版

    • 兼容 Bash 3.2+ 版本

    • 处理包含空格/特殊字符的文件名

这个脚本通过分阶段处理(先定位文件再过滤内容)有效提高了大文件集的搜索效率,同时保持输出的精确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值