diff --git a/ace-base.config b/ace-base.config index 4e917cb..0456f83 100644 --- a/ace-base.config +++ b/ace-base.config @@ -1,4 +1,4 @@ @PKG_NAME@=amber-ce-bookworm @HOST_NAME@=Amber-CE-Bookworm @EXEC_NAME@=bookworm-run -@PRETTY_NAME@=Bookworm \ No newline at end of file +@PRETTY_NAME@=Bookworm diff --git a/replacer.sh b/replacer.sh index 612cb07..eb5db91 100644 --- a/replacer.sh +++ b/replacer.sh @@ -1,62 +1,91 @@ -#!/bin/bash +#!/usr/bin/env bash -# 读取配置文件并解析键值对 -declare -A REPLACEMENTS -while IFS='=' read -r key value; do - [[ $key =~ ^@.*@$ ]] || continue # 仅处理形如 @VAR@ 的键 - REPLACEMENTS["$key"]="$value" -done < ace-base.config - -# 目标目录(默认当前目录) +######################################## +# 配置部分 +######################################## +config_file="ace-base.config" # 配置文件路径 if [[ -z "$1" ]];then -echo "Need appoint target dir." +echo "Need TARGET DIR" exit fi +target_dir="${1}" # 要处理的目标目录 +######################################## +# 读取 ace-base.config 生成替换字典 +######################################## +declare -A replacements -TARGET_DIR="${1}" - -# 替换文件内容 -replace_in_files() { - local file="$1" - local temp_file="${file}.tmp" - - # 遍历所有替换规则 - cp "$file" "$temp_file" - for key in "${!REPLACEMENTS[@]}"; do - sed -i "s|$key|${REPLACEMENTS[$key]}|g" "$temp_file" - done - - # 确保有更改后才覆盖原文件 - if ! cmp -s "$file" "$temp_file"; then - mv "$temp_file" "$file" - echo "Updated content in: $file" - else - rm "$temp_file" +while IFS= read -r line; do + # 跳过空行 + [[ -z "$line" ]] && continue + + # 匹配类似 @PKG_NAME@=amber-ce-bookworm 的格式 + if [[ "$line" =~ ^@(.*)@=(.*)$ ]]; then + key="${BASH_REMATCH[1]}" + val="${BASH_REMATCH[2]}" + replacements["$key"]="$val" fi +done < "$config_file" + +######################################## +# 第一步:文本文件内容替换 +######################################## +# 定义一个函数来判断文件是否是文本文件(示例仅供参考) +is_text_file() { + local f="$1" + file --mime-type "$f" | grep -q "text/" } -# 递归扫描目录,处理文本文件的内容 -find "$TARGET_DIR" -type f | while read -r file; do - if file --mime-type "$file" | grep -q 'text/'; then - replace_in_files "$file" +# 查找所有文件,逐一判断是否文本类型,如果是则进行内容替换 +find "$target_dir" -type f -print0 | while IFS= read -r -d '' file; do + if is_text_file "$file"; then + for key in "${!replacements[@]}"; do + # 用 sed 对文件内容进行替换 + sed -i "s|@$key@|${replacements[$key]}|g" "$file" + done fi done -# 处理文件名和目录名 -find "$TARGET_DIR" -depth | while read -r old_name; do - new_name="$old_name" - - # 替换文件名中的占位符 - for key in "${!REPLACEMENTS[@]}"; do - new_name="${new_name//$key/${REPLACEMENTS[$key]}}" +######################################## +# 第二步:先重命名文件 +######################################## +find "$target_dir" -type f -print0 | while IFS= read -r -d '' file; do + # 拆分目录和文件名 + dir_path="$(dirname "$file")" + filename="$(basename "$file")" + + newfilename="$filename" + for key in "${!replacements[@]}"; do + newfilename="${newfilename//@$key@/${replacements[$key]}}" done - # 如果名称有变化,则重命名 - if [[ "$old_name" != "$new_name" ]]; then - mv "$old_name" "$new_name" - echo "Renamed: $old_name -> $new_name" + # 如果新文件名和原文件名不同,则执行重命名 + if [[ "$newfilename" != "$filename" ]]; then + mv -v "$file" "$dir_path/$newfilename" fi done -echo "Processing completed." +######################################## +# 第三步:再重命名目录(由浅到深) +######################################## +# 先按目录层级进行排序(层数少的先处理) +# awk -F/ '{print NF, $0}' 会将路径按 / 分割并统计层数,然后 sort -n 升序,层数越小越先处理 +find "$target_dir" -type d | awk -F/ '{print NF, $0}' | sort -n | cut -d' ' -f2- | while IFS= read -r dir; do + # 如果要连同最顶层目录一起改名,可以保留;若不需要改最顶层,可以加条件跳过 + # [ "$dir" = "$target_dir" ] && continue # 如需跳过顶层可取消注释 + + parent_path="$(dirname "$dir")" + dirname_only="$(basename "$dir")" + + newdirname="$dirname_only" + for key in "${!replacements[@]}"; do + newdirname="${newdirname//@$key@/${replacements[$key]}}" + done + + # 需要改名则执行 + if [[ "$newdirname" != "$dirname_only" ]]; then + mv -v "$dir" "$parent_path/$newdirname" + fi +done + +echo "处理完成!"