首页 > 解决方案 > bash 逐行更改文件中的绝对路径以创建脚本

问题描述

我正在尝试基于输入文件(list.txt)创建一个 bash 脚本。输入文件包含具有绝对路径的文件列表。输出应该是一个 bash 脚本 (move.sh),它将文件移动到另一个位置,保留文件夹结构,但稍微更改目标文件夹名称。

输入 list.txt 文件示例如下所示:

/In/Folder_1/SomeFoldername1/somefilename_x.mp3
/In/Folder_2/SomeFoldername2/somefilename_y.mp3
/In/Folder_3/SomeFoldername3/somefilename_z.mp3

创建后的输出文件 (move.sh) 应如下所示:

mv "/In/Folder_1/SomeFoldername1/somefilename_x.mp3"  /gain/Folder_1/
mv "/In/Folder_2/SomeFoldername2/somefilename_y.mp3"  /gain/Folder_2/
mv "/In/Folder_3/SomeFoldername3/somefilename_z.mp3"  /gain/Folder_3/

应该或多或少地保留文件夹结构。

执行创建的 bash 脚本 (move.sh) 后,结果应如下所示:

/gain/Folder_1/somefilename_x.mp3
/gain/Folder_2/somefilename_y.mp3
/gain/Folder_3/somefilename_z.mp3

到目前为止我所做的。

1.创建具有绝对路径的文件列表

find /In/ -iname "*.mp3" -type f > /home/maars/mp3/list.txt

2.创建move.sh脚本

cp -a /home/maars/mp3/list.txt /home/maars/mp3/move.sh 
# read the list and split the absolute path into fields
while IFS= read -r line;do
fields=($(printf "%s" "$line"|cut -d'/' --output-delimiter=' ' -f1-))
done < /home/maars/mp3/move.sh
# add the target path based on variables at the end of the line
sed -i -E "s|\.mp3|\.mp3"\"" /gain/"${fields[1]}"/|g" /home/maars/mp3/move.sh
sed -i "s|/In/|mv "\""/In/|g" /home/maars/mp3/move.sh

该脚本仅使用 的值${fields[1]},即 Folder_1 并将其放在最后的所有行中。而不是 Folder_2 和 Folder_3。当前结果看起来像

mv "/In/Folder_1/SomeFoldername1/somefilename_x.mp3"  /gain/Folder_1/
mv "/In/Folder_2/SomeFoldername2/somefilename_y.mp3"  /gain/Folder_1/
mv "/In/Folder_3/SomeFoldername3/somefilename_z.mp3"  /gain/Folder_1/

rsync 不是一个选项,因为我需要完全控制要移动的文件。

我该怎么做才能更好地解决这个问题?

编辑:@Socowi 为我指明了正确的方向,给了我很多帮助。在我深入研究了正则表达式的世界之后,我可以解决我的问题。非常感谢

标签: bashseddirectorymoveabsolute-path

解决方案


它不是 bash 内置的,但该mmv命令非常适合mv需要在路径中使用通配符的这种情况。像下面这样的东西应该可以工作:

mmv "in/*/*/*" "#1/#3"

请注意,这不会为您创建目录 - 但在您上面的示例中,看起来这些目录已经存在?


推荐阅读