Unix下按文件名特征移动文件的Bash脚本无效果求助
文件移动脚本问题分析与解决
问题背景
需要将cds.gff目录下的abc1_cds.gff、abc2_cds.gff等文件,移动到当前目录下名称末尾匹配abc#的已存在文件夹(如example_name_abc1、example_name_abc2)。当前目录结构如下:
[Linux@vaughan test]$ tree . ├── cds.gff │ ├── abc1_cds │ ├── abc1_cds.gff │ ├── abc2_cds │ ├── abc2_cds.gff │ └── abc_cds ├── example_name_abc1 │ └── distraction_abc1.txt ├── example_name_abc2 │ └── abc2_distraction_abc2.txt └── move_files.sh
执行move_files.sh脚本后,文件位置无任何变化,原脚本内容如下:
#!/bin/bash # Iterate over files in the "cds.gff" directory for file in cds.gff/*.gff; do # Extract the filename without the path filename="${file##*/}" # Extract the last part of the folder name last_part_of_folder="${filename%_cds.gff}" # Check if there's a matching folder in the current directory if [ -d "$last_part_of_folder" ]; then # Move the file to the matching folder mv "$file" "$last_part_of_folder/" fi done
问题原因
脚本核心逻辑错误:
- 从文件名提取的
last_part_of_folder值为abc1、abc2,但实际目标文件夹名称是example_name_abc1、example_name_abc2,并非纯abc1或abc2。 - 脚本中的判断条件
[ -d "$last_part_of_folder" ]是检查当前目录下是否存在**名称完全等于abc1/abc2**的文件夹,而这类文件夹实际不存在,因此不会执行mv命令。
解决办法
修改脚本逻辑,改为查找当前目录下**名称末尾匹配abc1/abc2**的文件夹,而非严格匹配目录名。以下是两种可行的修改方案:
方案1:使用find命令定位目标文件夹
#!/bin/bash # 遍历cds.gff目录下的gff文件 for file in cds.gff/*.gff; do # 提取纯文件名(去掉路径) filename="${file##*/}" # 从文件名中提取标识符(abc1、abc2等) identifier="${filename%_cds.gff}" # 查找当前目录下以该标识符结尾的第一个目录 target_folder=$(find . -maxdepth 1 -type d -name "*${identifier}" | head -n 1) # 如果找到目标目录则移动文件 if [ -n "$target_folder" ]; then mv "$file" "$target_folder/" echo "已移动 $file 到 $target_folder" else echo "未找到 $file 对应的目标文件夹" fi done
方案2:使用通配符匹配目录
#!/bin/bash # 遍历cds.gff目录下的gff文件 for file in cds.gff/*.gff; do filename="${file##*/}" identifier="${filename%_cds.gff}" # 匹配所有以identifier结尾的目录 for folder in *"${identifier}"; do if [ -d "$folder" ]; then mv "$file" "$folder/" break # 找到第一个匹配目录后停止循环 fi done done
两种方案都能正确定位到example_name_abc1这类目标文件夹,完成文件移动操作。
内容的提问来源于stack exchange,提问作者Geomicro
相关产品推荐
相关产品推荐

