Bash扫描包含关键字的文件名并移动它们



我正在寻找一种方法来不断扫描文件夹树中包含MKV/MP4文件的新子文件夹。如果该文件包含一个关键字并以MP4或MKV结尾,它将被移动到与该关键字匹配的已定义位置。额外的好处是,它会删除文件之前所在的文件夹及其所有剩余内容。我们的想法是让它在后台运行,将所有东西分类到它所属的位置,并在可能的情况下自行清理。

示例:

MediaanimeTimmyTimmy_S1E1Timmy_S1E1_720p.mkv    #Found Keyword Timmy, allowed filetype

移动到目的地:

MediaseriesTimmy

删除子文件夹:

MediaanimeTimmyTimmy_S1E1

我会为每个关键字单独编写脚本,或者,如果可能的话,让脚本将每个关键字与目标匹配

#!/bin/bash
#!/bin/sh
#!/etc/shells/bin/bash
while true
do
shopt -s globstar
start_dir="//srv/MEDIA2/shows"                    
for name in "$start_dir"/**/*.*; do   
# search the directory recursively
done
sleep 300
done

这可以通过以下方式完成:

  • 创建一个脚本,一次性完成您想做的事情
  • 每隔一段时间从cron运行该脚本。比如说几分钟或几个小时,取决于您收到的文件量
  • 不需要持续运行的守护进程

例如:

#!/bin/bash
start_dir="/start/directory"
if [[ ! -d "$start_dir" ]]
then
echo "ERROR: start_dir ($start_dir) not found."
exit 1
fi
target_dir="/target/directory"
if [[ ! -d "$target_dir" ]]
then
echo "ERROR: target_dir ($target_dir) not found."
exit 1
fi
# Move all MP4 and MKV files to the target directory
find "$start_dir" -type f ( -name "*keyword*.MP4" -o -name "*keyword*.MKV" ) -print0 | while read -r -d $'' file
do
# add any processing here...
filename=$(basename "$file")
echo "Moving $filename to $target_dir..."
mv "$file" "$target_dir/$filename"
done
# That being done, all that is left in start_dir can be deleted
find "$start_dir" -type d ! -path "$start_dir" -exec /bin/rm -fr {} ;

详细信息:

  • 使用find命令扫描文件效率最高
  • -print0read ...的方法是确保所有有效的文件名都被处理,即使它们包括空格或其他"字符";怪异的";字符
  • 上面代码的结果是,每个与关键字匹配的扩展名为MP4或MKV的文件都将被处理一次
  • 然后可以使用"$file"访问当前循环中正在处理的文件
  • 请确保ALWAY双引号$file,否则任何奇怪的文件名都会阻止您的代码。无论如何,你应该总是对你的变量双引号
  • 可以根据您的特定需求添加更复杂的逻辑。例如,如果目标目录不存在,则创建该目录。根据关键字创建不同的目标目录。等等
  • 要删除$start_dir下的所有子目录,我使用find。同样,这将处理奇怪的目录名

有一点,有些人会争辩说,这一切都可以在带有-exec选项的1个find命令中完成。没错,但IMHO使用while循环的版本更容易编码、理解、调试和学习。

这个构造很适合放在bash工具箱中。


创建脚本时,只需要一行#!
我修复了你问题中的缩进,更容易阅读正确缩进和格式化的代码(请参阅问题编辑器中的编辑帮助(。


最后要讨论的一点是,假设您有大量目录和文件要处理,并且可能在脚本运行时添加新文件。例如,您正在移动许多MP4文件,在移动过程中,新文件会存放在目录中。然后,当您执行删除操作时,可能会丢失文件。

如果这种情况是可能的,您可以在执行/bin/rm之前添加对新文件的检查,这将有所帮助。可以肯定的是,您可以设置一个处理1个文件的脚本,并由inotify触发它。但这是另一场球赛,更加复杂,超出了这个答案的范围。

最新更新