这是一个非常实用的需求,特别是在需要将代码交给大模型(LLM)进行分析,或者进行代码归档时。
·
因为涉及文件重名处理逻辑(如果有重名,带上前缀;如果没有重名,保持原样),脚本需要分两步走:
- 第一步:扫描一遍,统计哪些文件名重复了。
- 第二步:执行复制和重命名。如果是重复的文件,就加上父目录名作为前缀。
这是一个完整的 Bash 脚本,你可以直接复制并在 Linux 终端中运行。
脚本代码 (collect_code.sh)
#!/bin/bash
# ================= 配置区域 =================
# 默认的源目录(如果没有输入参数,使用这个路径,或者报错)
# 这里设置为脚本接收的第一个参数
SOURCE_DIR="$1"
# 目标存放的根目录
TARGET_BASE_DIR="/home/woankeji/Documents"
# 新建的文件夹名称 (自动加上时间戳,防止覆盖之前的)
NEW_FOLDER_NAME="flattened_code_$(date +%Y%m%d_%H%M%S)"
DEST_DIR="$TARGET_BASE_DIR/$NEW_FOLDER_NAME"
# ================= 检查输入 =================
if [ -z "$SOURCE_DIR" ]; then
echo "❌ 错误: 请输入源目录路径。"
echo "用法: ./collect_code.sh <你的源代码目录>"
echo "示例: ./collect_code.sh ~/Desktop/osc-kvs-6262l/projects/wlab/osc/source"
exit 1
fi
if [ ! -d "$SOURCE_DIR" ]; then
echo "❌ 错误: 目录 '$SOURCE_DIR' 不存在。"
exit 1
fi
# ================= 准备工作 =================
echo "📂 源目录: $SOURCE_DIR"
echo "📂 目标目录: $DEST_DIR"
# 创建目标文件夹
mkdir -p "$DEST_DIR"
if [ $? -ne 0 ]; then
echo "❌ 无法创建目标目录,请检查权限。"
exit 1
fi
echo "🔍 正在扫描文件并计算文件名重复情况..."
# 定义一个关联数组来存储文件名出现的次数
declare -A file_counts
# 1. 第一遍扫描:统计文件名出现的次数
# 使用 find 查找所有 .c 和 .h 文件
while IFS= read -r file; do
filename=$(basename "$file")
# 计数加1
((file_counts["$filename"]++))
done < <(find "$SOURCE_DIR" -type f \( -name "*.c" -o -name "*.h" \))
echo "🚀 开始复制并重命名文件..."
# 2. 第二遍扫描:复制并重命名
count=0
while IFS= read -r file; do
filename=$(basename "$file")
# 获取该文件名在整个项目中出现的总次数
occurrence=${file_counts["$filename"]}
# 确定新文件名
if [ "$occurrence" -gt 1 ]; then
# === 冲突处理逻辑 ===
# 如果文件名有重复,获取它的直接父目录名称
parent_dir_path=$(dirname "$file")
parent_dir_name=$(basename "$parent_dir_path")
# 组合新名字: 父目录_文件名.txt
# 例如: common/utils.c -> common_utils.c.txt
new_filename="${parent_dir_name}_${filename}.txt"
# 极端的边缘情况:如果不同路径下父目录名也一样 (例如 a/common/utils.c 和 b/common/utils.c)
# 检查目标是否已经存在该文件,如果存在,再拼上一层目录或随机数
if [ -f "$DEST_DIR/$new_filename" ]; then
grandparent_name=$(basename "$(dirname "$parent_dir_path")")
new_filename="${grandparent_name}_${parent_dir_name}_${filename}.txt"
fi
else
# === 无冲突逻辑 ===
# 没有重名,直接加 .txt 后缀
new_filename="${filename}.txt"
fi
# 执行复制
cp "$file" "$DEST_DIR/$new_filename"
((count++))
# 打印进度 (可选)
# echo "复制: $filename -> $new_filename"
done < <(find "$SOURCE_DIR" -type f \( -name "*.c" -o -name "*.h" \))
echo "------------------------------------------------"
echo "✅ 完成!"
echo "📊 共处理文件: $count 个"
echo "📂 所有文件已保存在: $DEST_DIR"
echo " (你可以使用 'nautilus $DEST_DIR' 打开查看)"
如何使用这个脚本
-
保存脚本:
在你的终端中,创建一个文件,例如collect_code.sh:nano collect_code.sh把上面的代码粘贴进去,然后按
Ctrl+O保存,Ctrl+X退出。 -
赋予执行权限:
chmod +x collect_code.sh -
运行脚本:
将你的源码目录作为参数传进去:./collect_code.sh ~/Desktop/osc-kvs-6262l/projects/wlab/osc/source
脚本逻辑解析 (针对你的需求)
- 不改变原目录:脚本只执行
cp(复制) 操作,原目录下的任何文件都不会被修改。 - 目标目录:它会在
/home/woankeji/Documents下创建一个类似flattened_code_20231204_170000的新文件夹。 - 智能重命名逻辑:
- 脚本使用了
declare -A file_counts(关联数组) 先把所有.c和.h文件的名字统计了一遍。 - 情况 A (无重名):比如
wlab_at.c在整个目录里只出现了一次。- 结果:
wlab_at.c.txt
- 结果:
- 情况 B (有重名):比如
common/utils.c和wifi/utils.c,统计发现utils.c出现了 2 次。- 脚本会自动提取父目录名 (
common和wifi)。 - 结果:
common_utils.c.txt和wifi_utils.c.txt。
- 脚本会自动提取父目录名 (
- 脚本使用了
- 递归查找:使用
find命令自动深入所有子文件夹(如application/at,peripheral/adc等)。
预期输出效果
执行后,/home/woankeji/Documents/flattened_code_.../ 文件夹内将包含:
wlab_at.c.txtwlab_at.h.txtpower_control.c.txtcommon_utils.c.txt(假设存在重名)wifi_utils.c.txt(假设存在重名)apt32.c.txt- … 等等,全部在一个平面目录下。
更多推荐
所有评论(0)