implented replacer

This commit is contained in:
shenmo 2025-03-06 14:43:57 +08:00
parent 90bf57d884
commit ce6feba217
2 changed files with 75 additions and 46 deletions

@ -1,4 +1,4 @@
@PKG_NAME@=amber-ce-bookworm
@HOST_NAME@=Amber-CE-Bookworm
@EXEC_NAME@=bookworm-run
@PRETTY_NAME@=Bookworm
@PRETTY_NAME@=Bookworm

@ -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 "处理完成!"