Shell: 读配置文件并用逗号分割

本文介绍了一个使用Shell脚本从配置文件中读取并解析设置的例子。通过while循环逐行读取配置文件,并利用if条件判断来存储含有特定格式的数据到数组中。随后通过for循环遍历数组内容,按逗号分隔每一项设置,提取日志路径、名称及时间等信息。
List=()
cnt=0


while read line
do
  if [[ "$line" == "/"* ]]; then
    List[$cnt]="$line"
    cnt=$((cnt+1))
  fi
done < /home/username/settings.conf


echo "start split settings"
for Item in ${List[*]}
  do
    IFS=',' read -r -a logsets <<< "$Item"
    logpath=${logsets[0]}
    logname=${logsets[1]}
    logtime=${logsets[2]}
    ...
  done
exit 0
<think>我们有一个明确的任务:编写一个Shell脚本,遍历当前目录下的每个文件夹,删除除指定文件夹名之外的所有文件夹。根据之前的讨论,我们已经有一个脚本框架,但需要根据用户新的要求进行调整。用户要求参考了站内引用,特别是关于处理带空格文件夹名和从文件读取路径的内容。但是,本任务并不需要从文件读取路径,而是直接处理当前目录下的文件夹。另外,用户强调要避免误删,并且处理带空格的文件名。关键点:1.遍历当前路径下的所有文件夹(非文件)。2.保留指定的文件夹(可能不止一个),删除其他的文件夹。3.安全措施:避免误删,尤其是避免删除当前目录(.)或父目录(..)以及系统目录。4.正确处理文件夹名中的空格和特殊字符。步骤:a)定义要保留的文件夹列表(用空格分隔,如:KEEP_FOLDERS="folder1folder2")。b)遍历当前目录下的每个文件夹(使用通配符*/,并去除尾部斜杠)。c)对于每个文件夹,检查它是否在保留列表中。如果在,则跳过;如果不在,则删除。注意:rm-rf会递归删除整个文件夹,所以必须非常小心。我们将采用以下安全措施:-在删除前打印将要删除的文件夹(用户可以先运行测试模式)-可以设置一个测试模式变量,默认不实际删除,用户确认后再改为实际删除-记录操作日志根据用户提供的引用[3]和[5],我们需要注意带空格的文件夹名,所以在变量引用时都要用双引号。修改计划:我们提供一个参数(-e或--execute)来控制是否实际执行删除。默认情况下只显示将要删除的内容,不实际删除。用户只有在确认无误后,加上参数-e才会实际删除。脚本结构:1.定义保留文件夹列表2.定义测试模式(默认是,即不删除)3.解析参数,如果传入-e或--execute,则测试模式关闭(实际删除)4.遍历当前目录下的每个文件夹5.跳过保留的文件夹6.对于非保留的文件夹,如果是测试模式,则打印删除预览;否则实际删除,并记录日志此外,我们还需要避免删除当前目录(.)和父目录(..),但通配符*/不会匹配到.和..,所以安全。我们添加一个日志功能,记录操作。代码实现:注意:在Shell中,文件夹名可能包含空格,所以循环变量和rm命令中的变量都要用双引号括起来。我们使用一个数组来存储保留的文件夹,但是用户定义的是空格分隔的字符串。这样处理比较方便,因为文件夹名中可能没有空格?但用户可能有空格,所以保留列表也可能包含带空格的文件夹名?我们暂时要求保留列表中的文件夹名不要包含空格(因为用空格分隔),如果有空格,用户可以用数组的方式定义,但为了简单,我们使用字符串,用户可以用引号括起每个文件夹名吗?实际上,在for循环中,字符串按空格拆分,所以不行。因此,我们要求保留的文件夹名中不能有空格,或者用户用其他方式(比如转义)?但这样复杂。替代方案:允许用户将保留的文件夹名用逗号分隔,或者使用数组。但为了简单,我们仍然使用空格分隔,并假设保留文件夹名不包含空格。如果包含空格,那么用户需要自己用转义或者引号,但这样在for循环中也会被拆开。另一种方案:使用数组。例如:KEEP_FOLDERS=("importantfolder""backupfolder")然后循环的时候用"${KEEP_FOLDERS[@]}",这样每个元素都可以包含空格。我们选择使用数组,这样更安全,但用户需要按照数组的方式填写。不过,用户输入时在脚本中写数组不太方便(因为用户可能不熟悉数组),所以我们还是先用空格分隔,但提醒用户文件夹名不要有空格。或者我们让用户用竖线|分隔?不,还是用数组。但为了兼容性(使用bash),我们在脚本开头指定#!/bin/bash。我们决定使用数组,这样用户可以在数组中直接写带空格的文件夹名(用引号括起来)。例如:KEEP_FOLDERS=("importantfolder"backup"anotherfolder")但如果用户想用变量,并且变量包含空格,那么写成数组的形式是最安全的。如果用户不熟悉数组,我们也可以使用字符串数组(用空格分隔),但要求文件夹名不要有空格。因为任务中用户并没有要求保留带空格的文件夹名,我们可以先按无空格处理,并在注释中说明。折中方案:在脚本中允许用户用空格分隔,但是如果保留的文件夹名包含空格,那么用户必须使用数组的语法。我们提供两种方式的示例。为了简单,我们先按照无空格处理(因为带空格的文件夹名在保留列表中出现的概率不高,而且删除操作中我们使用双引号引用文件夹名,所以即使要删除的文件夹有空格也能正确处理)。如果保留的文件夹名包含空格,那么用户需要以数组方式定义。我们将在脚本中注释说明。我们将这样写:#保留文件夹列表,支持空格分隔的字符串(但每个文件夹名不要包含空格),或者数组(支持包含空格)#方式1(无空格):KEEP_FOLDERS="folder1folder2"#方式2(有空格):KEEP_FOLDERS=("folder1""folder2"folder3)然后通过参数判断,如果是字符串,就拆成数组;但为了简单,我们直接使用数组。我们要求用户使用数组语法吗?不,我们可以自动判断:如果用户定义的是字符串,就按空格拆分成数组;如果是数组,就直接用。但无法同时支持。所以,我们让用户选择一种方式,并推荐如果文件夹名没有空格,用字符串;如果有空格,用数组。但用户可能不会写数组,所以我们将提供两个变量定义行,让用户注释掉不需要的。但这样用户容易出错。因此,我们决定使用单一方式:字符串数组,并要求用户将文件夹名用引号括起来,并用空格分隔?不行,用空格分隔的字符串无法表示带空格的文件夹名。所以,我们采用数组。我们在注释中给用户示例,使用数组定义。脚本内容:完整脚本如下:</think> 以下是一个安全可靠的 Linux Shell 脚本,用于遍历当前路径下的文件夹,保留指定文件夹并删除其他文件夹: ```bash #!/bin/bash # 遍历当前目录,删除除指定文件夹外的所有文件夹 # ===== 配置区域 ===== KEEP_FOLDERS=("重要数据" "备份文件") # 需要保留的文件夹名称(支持带空格名称) ENABLE_DELETE=true # true=实际执行删除 false=只预览不删除 LOG_FILE="./folder_cleanup_$(date +%Y%m%d_%H%M%S).log" # 操作日志文件 # ===== 配置结束 ===== echo "🔍 开始扫描目录: $(pwd)" echo "🛡️ 保留的文件夹: ${KEEP_FOLDERS[*]}" echo "📝 操作日志: $LOG_FILE" echo "================================================" > "$LOG_FILE" echo "文件夹清理日志 ($(date))" >> "$LOG_FILE" echo "保留文件夹: ${KEEP_FOLDERS[*]}" >> "$LOG_FILE" echo "------------------------------------------------" >> "$LOG_FILE" # 计数器 deleted_count=0 kept_count=0 # 安全检测:避免在根目录或重要目录执行 if [[ $(pwd) == "/" ]] || [[ $(pwd) == "/home" ]] || [[ $(pwd) == "/etc" ]]; then echo "❌ 错误:不能在系统关键目录 $(pwd) 执行此操作!" exit 1 fi # 遍历所有文件夹 while IFS= read -r -d $'\0' folder; do folder_name=$(basename "$folder") should_delete=true # 检查是否为保留文件夹 for keep in "${KEEP_FOLDERS[@]}"; do if [[ "$folder_name" == "$keep" ]]; then should_delete=false break fi done # 处理文件夹 if $should_delete; then if [[ "$ENABLE_DELETE" == true ]]; then echo "🗑️ 删除文件夹: $folder_name" rm -rf "$folder" echo "已删除: $folder_name" >> "$LOG_FILE" ((deleted_count++)) else echo "预览删除: $folder_name" echo "预览删除: $folder_name" >> "$LOG_FILE" fi else echo "✅ 保留文件夹: $folder_name" echo "已保留: $folder_name" >> "$LOG_FILE" ((kept_count++)) fi done < <(find . -maxdepth 1 -type d ! -name "." -print0) # 生成报告 echo "================================================" echo "📊 操作完成:" echo " 保留文件夹: $kept_count" if [[ "$ENABLE_DELETE" == true ]]; then echo " 删除文件夹: $deleted_count" else echo " 预览删除: $deleted_count (未实际执行)" fi echo "📝 详情请查看日志: $LOG_FILE" # 重要提示 if [[ "$ENABLE_DELETE" == false ]]; then echo "⚠️ 当前为预览模式,要实际执行删除请修改ENABLE_DELETE=true" fi echo "================================================" ``` ### 使用说明 1. **配置参数**: - `KEEP_FOLDERS`: 要保留的文件夹列表(支持含空格名称) - `ENABLE_DELETE`: 设置为 `true` 时实际删除,`false` 时只预览 2. **安全执行步骤**: ```bash # 第一步:预览模式(不实际删除) ./clean_script.sh # 第二步:确认预览结果无误后,修改脚本配置 ENABLE_DELETE=true # 第三步:实际执行删除 ./clean_script.sh ``` 3. **安全特性**: - 使用 `find -print0` 和 `read -d $'\0'` 处理含空格/特殊字符的路径名[^3] - 防止在系统关键目录(`/`, `/home`, `/etc`)执行 - 自动生成带时间戳的操作日志 - 支持预览模式防止误操作 - 详细的执行统计报告 ### 应用场景 1. 清理构建目录(保留`dist/`文件夹) 2. 项目结构优化(保留`src/`和`docs/`) 3. 临时文件清理(保留日志文件夹)[^1] 4. CI/CD 流水线工作区维护 ### 安全建议 1. 首次使用时始终保持 `ENABLE_DELETE=false` 2. 通过 `find . -type d` 验证目录结构 3. 重要文件夹使用只权限:`chmod a-w 重要文件夹` 4. 使用版本控制(如git)作为额外保护层[^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值