我正在尝试通过创建 Linux 脚本(Bash)将文件按模式排序为文件名。
我的文件主要是 .JPG,一些 .AV 和 .MP4。我无法使用元标记,因为该文件的标记已损坏(从 RAID 崩溃中恢复)。
我的大部分文件都带有这样的标签 Seaxxx_A01_xxx.jpg 或 Beach_xxx_A01A02_xxx.jpg 或 Mountain_xxx_A04A12_xxx.jpg (这是我对拍摄照片和设备的参考,即:相机、反射等...)。
我的需要是根据文件名将文件放入正确的文件夹和子文件夹中。
我认为这样完成这个任务:
使用find,查找模式[AZ][0-2][0-6]或[AZ][0-2][0-6][AZ][0-2][0-6],当这个模式找到后,查找文件名的第一个部分(即大海、海滩、山、家庭等...,始终作为第一个单词放置,通常我之前没有其他任何内容)并使用第一部分来查找一个具有相似名称的文件夹并将其放入(如果我的文件包含:Sea_Royan_xxx_A04A10_xxx.jpg 并且我只有一个名为“Sea”的文件夹,则必须将其放入其中)。
在每个文件夹上,都存在子文件夹,例如 A01、A02、A03、A04 或 Dio、Sandy、Mael 等...并且我想要当前找到的文件(即与用于放入父文件夹 Sea 的文件相同)山等...)检查上面列出的第二个模式,用于放置正确的子文件夹。
事实上,更简单的是,我需要:查找文件,找到后,检查文件名并使用两种模式将其移动到正确的文件夹和子文件夹中。
让我知道如何做到这一点(我知道如何根据模式查找文件,但不知道如何读取当前找到的文件名,并在此文件名上检查两个模式以用作正确的路径),如果您有更多最简单的方法或更好的方法请随时告诉我!
答案1
这是一种可能的方法,但它可能不是最美丽的也不是最原始的。这个想法是在 awk 中使用正则表达式从文件名中提取相关位。然后我们继续在 awk 中构建 shell move (mv) 命令。最后,我们使用 awk 中可用的系统命令来执行该命令并将文件移动到正确的子文件夹中。
首先尝试这样做以获得详细的描述:
find . -mindepth 1 -maxdepth 1 -type f | awk '{ filename=$0; match(filename, "^([^_]+).*_(A.*)_", capture); folder=capture[1]; subfolder=capture[2]; cmd=("mv " "" filename " " folder "/" subfolder); print "Command to be run: ", cmd }'
结果:
Command to be run: mv ./Seaxxx_A01_xxx.jpg ./Seaxxx/A01
Command to be run: mv ./Mountain_xxx_A04A12_xxx.jpg ./Mountain/A04A12
Command to be run: mv ./Beach_xxx_A01A02_xxx.jpg ./Beach/A01A02
要实际执行命令,请在语句末尾添加 system(cmd):
find . -mindepth 1 -maxdepth 1 -type f | awk '{ filename=$0; match(filename, "^([^_]+).*_(A.*)_", capture); folder=capture[1]; subfolder=capture[2]; cmd=("mv " "" filename " " folder "/" subfolder); print "Command to be run: ", cmd; system(cmd) }'
您可能想要的一件事是根据您的需要调整正则表达式。我假设您熟悉正则表达式,这里我们捕获文件名的两个部分。捕获组括在括号内。
从文件名的开头开始,我们抓取所有非下划线的内容,直到找到一个下划线。然后我们继续寻找,直到找到模式 A######,其中 # 代表字母/数字(第二个捕获组)。我们捕获直到按下下一个下划线。