Bash扫描包含关键字的文件名并移动它们
我正在寻找一种方法,不断扫描文件夹树,寻找包含MKV/MP4文件的新子文件夹。如果该文件包含关键字并以MP4或MKV结尾,它将被移动到与该关键字匹配的定义位置。作为奖励,它将删除文件夹以及文件先前所在的所有剩余内容。我们的想法是在后台运行这个程序,将所有的东西分类,如果可能的话,进行清理 例如:Bash扫描包含关键字的文件名并移动它们,bash,Bash,我正在寻找一种方法,不断扫描文件夹树,寻找包含MKV/MP4文件的新子文件夹。如果该文件包含关键字并以MP4或MKV结尾,它将被移动到与该关键字匹配的定义位置。作为奖励,它将删除文件夹以及文件先前所在的所有剩余内容。我们的想法是在后台运行这个程序,将所有的东西分类,如果可能的话,进行清理 例如: Media\anime\Timmy\Timmy_S1E1\Timmy_S1E1_720p.mkv #Found Keyword Timmy, allowed filetype 移动到目的地: M
Media\anime\Timmy\Timmy_S1E1\Timmy_S1E1_720p.mkv #Found Keyword Timmy, allowed filetype
移动到目的地:
Media\series\Timmy\
删除子文件夹:
Media\anime\Timmy\Timmy_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运行脚本。比如说几分钟,或者几小时,取决于你收到的文件量
- 不需要持续运行的守护进程
- 使用
命令扫描文件最有效find
with-print0
方法用于确保处理所有有效文件名,即使它们包含空格或其他“怪异”字符read…
- 上述代码的结果是,每个与关键字匹配的文件(扩展名为MP4或MKV)将被处理一次
- 然后可以使用
访问当前循环中正在处理的文件“$file”
- 确保始终双引号
,否则任何奇怪的文件名都会阻止您的代码。无论如何,你都应该双引号引用你的变量$file
- 可以根据您的具体需要添加更复杂的逻辑。例如,如果目标目录不存在,则创建该目录。根据关键字创建不同的目标目录。等等
- 要删除
下的所有子目录,我使用$start\u dir
。这将再次处理奇怪的目录名find
有一点,有些人会争辩说,这一切都可以在1
find
命令和-exec
选项中完成。是的,但是使用while
循环的版本更容易编码、理解、调试和学习
这个构造很适合放在bash工具箱中
创建脚本时,只有一个
#需要代码>行。
我修复了问题中的缩进,更容易阅读正确缩进和格式化的代码(请参阅问题编辑器中的编辑帮助)
最后要讨论的一点是,假设您要处理大量目录和文件,并且在脚本运行时可能会添加新文件。例如,您正在移动许多MP4文件,在移动过程中,新文件存放在目录中。然后,当您执行删除操作时,可能会丢失文件
如果可能出现这种情况,您可以在执行/bin/rm
之前添加新文件的检查,这会有所帮助。当然,您可以设置一个处理1个文件的脚本,并通过inotify
触发它。但那是另一场球赛,更复杂且超出此答案的范围。`如果该文件包含关键字并以MP4或MKV结尾`如果该文件包含关键字或文件名包含关键字?请首先在粘贴脚本,并尝试执行此处提出的建议。实际上,您可以使用find
在不使用任何关键字的情况下进行本机删除执行官rm-f。查看手册中的-empty
和-delete
参数。例如,你可以做一些事情,比如find-typed-mtime+21-empty-delete
,它会删除21天内没有被碰过的空目录,这真是一个不错的补充。
#!/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 $'\0' 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 {} \;