
直接上干货
linux脚本
shell
#!/bin/bash
# ==============================================
# 脚本名称:git_changes_extractor.sh
# 功能:提取指定时间范围内的Git修改文件到目标目录
# 创建日期:2023-12-27
# ==============================================
# 项目根目录(根据您提供的路径)
# 这是要提取Git变更文件的源项目目录
PROJECT_ROOT="/media/consola/test/coding/company/bussness/gui_yang/ueba/base/project/ueba"
# 目标目录(要求的路径)
# 提取的文件将被复制到这个目录中
TARGET_DIR="/media/consola/test/coding/study/202512/EasyUI-Jquery/note/2025-12-26/git提取要提交的代码"
# 确保目标目录存在
# -p 参数:如果目录不存在则创建,如果已存在也不会报错
mkdir -p "$TARGET_DIR"
# 进入项目根目录执行 Git 操作
# 使用cd命令切换到项目目录,如果切换失败则输出错误信息并退出脚本
cd "$PROJECT_ROOT" || {
echo "❌ 项目路径不存在: $PROJECT_ROOT"
exit 1
}
# ==============================================
# Git日志提取和处理流程
# ==============================================
# 提取修改文件列表(已过滤指定路径,保留原始文件路径)
# 使用git log命令获取2025年12月25日到12月26日之间的提交记录
git log --since="2025-12-25" --until="2025-12-26" \
--pretty=format:'%ad | %an |' --date=format:'%Y-%m-%d %H:%M:%S' \
--name-only | \
# 过滤掉不需要的目录:排除linkgraph目录下的文件
grep -v '^link_data_knowledge/src/main/resources/static/linkgraph/' | \
# 使用awk处理输出:
# -F'|' 设置字段分隔符为竖线
# NF==1 表示只有一列(即文件路径行,因为提交信息行有竖线分隔符)
# $1!="" 排除空行
# 最终输出文件路径
awk -F'|' 'NF==1 && $1!="" {print $1}' | \
# 排序并去重:确保相同的文件路径只出现一次
sort | uniq | \
# 逐行读取处理每个文件路径
while read file_path; do
# 构建源文件和目标文件路径
# 源文件:项目根目录 + 文件相对路径
src_file="$PROJECT_ROOT/$file_path"
# 目标文件:目标目录 + 文件相对路径
dest_file="$TARGET_DIR/$file_path"
# 创建目标目录(如果不存在)
# dirname命令提取文件路径中的目录部分
# mkdir -p 递归创建目录结构
mkdir -p "$(dirname "$dest_file")"
# 复制文件(跳过不存在的文件)
# -f 参数检查是否为普通文件(排除目录、符号链接等)
if [ -f "$src_file" ]; then
# 使用cp命令复制文件到目标位置
cp "$src_file" "$dest_file"
echo "✅ 已复制: $file_path"
else
# 如果源文件不存在,输出警告信息
echo "⚠️ 跳过 (不存在): $file_path"
fi
done
# ==============================================
# 结果统计和输出
# ==============================================
# 统计复制的文件数量
# find命令:在目标目录中查找所有普通文件
# wc -l:统计行数(即文件数量)
file_count=$(find "$TARGET_DIR" -type f | wc -l)
# 输出完成信息
echo -e "\n🎉 复制完成! 共复制 $file_count 个文件"
echo "📁 目标目录: $TARGET_DIR"
# ==============================================
# 使用说明:
# 1. 修改PROJECT_ROOT和TARGET_DIR变量为实际路径
# 2. 修改--since和--until参数为需要的时间范围
# 3. 根据需要调整grep过滤规则
# 4. 给脚本添加执行权限:chmod +x git_changes_extractor.sh
# 5. 运行脚本:./git_changes_extractor.sh
# ==============================================
win脚本(CMD命令执行)
因为 powershell执行的ps1 文件环境有点复杂没有写,cmd够用了
shell
@echo off
:: 关闭命令回显,使脚本运行时不会显示执行的命令
chcp 65001 >nul 2>&1
:: 将控制台代码页设置为UTF-8(65001),以支持中文字符显示
:: >nul 2>&1 表示将标准输出和错误输出都重定向到空设备,不显示任何信息
setlocal enabledelayedexpansion
:: 启用延迟环境变量扩展,允许在代码块内使用!var!访问变量的动态值
:: ==============================================
:: 配置参数部分
:: ==============================================
:: 项目根目录 - 要提取Git变更文件的源项目路径
set "PROJECT_ROOT=E:\WorkSpace\ZhongJinHuiAn\project\GuiYang\ueba"
:: 目标目录 - 提取的文件将被复制到这个目录
set "TARGET_DIR=C:\Users\consola\Downloads\TestJpg\TestJpg\20251226\temp01"
:: 开始日期 - Git日志查询的起始日期
set "START_DATE=2025-12-25"
:: 结束日期 - Git日志查询的截止日期
set "END_DATE=2025-12-26"
:: 排除路径模式 - 匹配这个模式的文件路径将被跳过(注意:反斜杠要转义)
:: 这里排除了linkgraph目录下的所有文件
set "excludePattern=link_data_knowledge\\src\\main\\resources\\static\\linkgraph\\"
:: ==============================================
:: 目录准备部分
:: ==============================================
:: 进入项目目录
cd /d "%PROJECT_ROOT%" || (
:: 如果目录切换失败,显示错误信息并暂停
echo ❌ 无法进入项目目录: %PROJECT_ROOT%
pause
exit /b 1 :: 退出脚本,返回错误代码1
)
:: 创建目标目录(如果不存在)
if not exist "%TARGET_DIR%" md "%TARGET_DIR%"
:: ==============================================
:: Git日志提取部分
:: ==============================================
echo 🕒 正在提取修改的文件...
echo.
:: 创建一个临时文件来存储Git命令的输出
:: %TEMP% 是Windows环境变量,指向临时文件夹
:: %RANDOM% 生成随机数,确保文件名唯一
set "TEMP_FILE=%TEMP%\git_whatchanged_%RANDOM%.txt"
:: 执行git whatchanged命令获取修改文件列表
:: --since 和 --until: 指定时间范围
:: --name-only: 只显示文件名,不显示提交信息
:: --oneline: 每个提交显示在一行中
:: > "%TEMP_FILE%": 将输出重定向到临时文件
:: 2>nul: 将错误信息重定向到空设备,不显示
git whatchanged --since="%START_DATE%" --until="%END_DATE%" --name-only --oneline > "%TEMP_FILE%" 2>nul
:: ==============================================
:: 文件处理部分
:: ==============================================
:: 初始化计数器
set "fileCount=0" :: 找到的文件总数(去重后)
set "filesCopied=0" :: 成功复制的文件数
echo 📋 找到的修改文件:
echo =========================================
:: 使用for循环逐行读取临时文件内容
:: /f "tokens=*": 读取整行内容
:: %%a: 循环变量,代表当前行
for /f "tokens=*" %%a in ('type "%TEMP_FILE%" ^| findstr /v "^[a-f0-9][a-f0-9]*\s" ^| findstr /v "^$" ^| findstr /v "^:"') do (
:: 获取文件路径
set "filePath=%%a"
:: 将路径中的正斜杠(/)转换为反斜杠(\),适应Windows路径格式
set "filePath=!filePath:/=\!"
:: 检查文件路径是否为空
if not "!filePath!"=="" (
:: 去重检查:使用动态变量名确保每个文件只处理一次
:: FILE_!filePath! 是一个动态命名的变量,如果未定义,则说明文件未处理过
if not defined FILE_!filePath! (
:: 标记文件已处理
set "FILE_!filePath!=1"
:: 排除检查:如果文件路径包含排除模式,则跳过
:: findstr /i: 不区分大小写搜索
:: >nul: 将输出重定向到空设备
echo !filePath! | findstr /i "!excludePattern!" >nul
:: errorlevel 1 表示没有匹配到排除模式
if errorlevel 1 (
:: 文件不在排除路径中
if exist "!filePath!" (
:: 显示文件路径
echo 📄 !filePath!
:: 文件计数加1
set /a fileCount+=1
:: 构建目标文件路径
set "destPath=%TARGET_DIR%\!filePath!"
:: 提取目标文件所在目录
:: %%~dpF: 提取完整路径的驱动器和目录部分
for %%F in ("!destPath!") do set "destDir=%%~dpF"
:: 创建目标目录(如果不存在)
if not exist "!destDir!" md "!destDir!" >nul 2>&1
:: 复制文件
:: /y: 覆盖现有文件不提示
:: >nul 2>&1: 不显示复制信息
copy /y "!filePath!" "!destPath!" >nul 2>&1
:: 检查复制是否成功
if !errorlevel! equ 0 (
:: 复制成功,计数器加1
set /a filesCopied+=1
echo ✅ 已复制: !filePath!
) else (
:: 复制失败
echo ❌ 复制失败: !filePath!
)
) else (
:: 源文件不存在
echo ⚠️ 源文件不存在: !filePath!
)
) else (
:: 文件在排除路径中,跳过
echo ⚠️ 跳过(排除路径): !filePath!
)
)
)
)
:: ==============================================
:: 清理和结果输出部分
:: ==============================================
:: 删除临时文件
del "%TEMP_FILE%" >nul 2>&1
echo =========================================
echo.
:: 根据复制结果输出相应信息
if %filesCopied% equ 0 (
echo 📌 未找到或复制任何文件
) else (
echo 🎉 共复制 %filesCopied% 个文件
)
:: 显示执行摘要
echo 📁 目标目录: %TARGET_DIR%
echo 🔍 排除路径: %excludePattern%
:: 暂停,等待用户按键继续
pause
:: ==============================================
:: 脚本说明:
:: 1. 本脚本用于在Windows环境下提取指定时间段内的Git修改文件
:: 2. 支持排除特定路径的文件
:: 3. 自动创建目标目录结构
:: 4. 只复制实际存在的文件
:: 5. 提供详细的执行过程反馈
:: ==============================================