Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash扫描包含关键字的文件名并移动它们_Bash - Fatal编程技术网

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

Bash扫描包含关键字的文件名并移动它们,bash,Bash,我正在寻找一种方法,不断扫描文件夹树,寻找包含MKV/MP4文件的新子文件夹。如果该文件包含关键字并以MP4或MKV结尾,它将被移动到与该关键字匹配的定义位置。作为奖励,它将删除文件夹以及文件先前所在的所有剩余内容。我们的想法是在后台运行这个程序,将所有的东西分类,如果可能的话,进行清理 例如: Media\anime\Timmy\Timmy_S1E1\Timmy_S1E1_720p.mkv #Found Keyword Timmy, allowed filetype 移动到目的地: M

我正在寻找一种方法,不断扫描文件夹树,寻找包含MKV/MP4文件的新子文件夹。如果该文件包含关键字并以MP4或MKV结尾,它将被移动到与该关键字匹配的定义位置。作为奖励,它将删除文件夹以及文件先前所在的所有剩余内容。我们的想法是在后台运行这个程序,将所有的东西分类,如果可能的话,进行清理

例如:

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
    命令扫描文件最有效
  • -print0
    with
    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 {} \;