如果日志很多,又需要针对某个目录下面的日志文件,进行关键字定位,并过滤不包含某些关键字的日志文件,初步定位一部分符合的日志文件,以便后续针对符合的日志文件,人工介入做详细分析。
脚本原文
#!/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:从结果中排除包含任何排除关键字的文件
-
输出:最终符合条件的文件名列表
-
-
技术亮点:
-
使用
-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
注意事项
-
性能优化:
-
大目录搜索时添加
--include=*.log限制文件类型 -
使用
--exclude-dir={cache,tmp}排除目录 -
超大文件集考虑添加
--max-depth=3限制搜索深度
-
-
高级用法:
# 仅搜索 .py 文件并排除 test 目录 ./smart_grep.sh ~/project \ "import module" \ "test mock" \ --include="*.py" \ --exclude-dir=test -
兼容性:
-
支持所有现代 Linux 发行版
-
兼容 Bash 3.2+ 版本
-
处理包含空格/特殊字符的文件名
-
这个脚本通过分阶段处理(先定位文件再过滤内容)有效提高了大文件集的搜索效率,同时保持输出的精确性。


3399

被折叠的 条评论
为什么被折叠?



