使用 BASH 脚本扫描子文件夹 ${ROOTPATH}/${subdir}

使用 BASH 脚本扫描子文件夹 ${ROOTPATH}/${subdir}

我尽最大努力完成这项工作,但对脚本编写知之甚少。该脚本应该扫描我指定的目录和所有子目录,扫描视频资源,将任何损坏/错误的文件移动到已创建的 00errors 文件夹中。

我可以让一切正常工作,接受扫描所有子目录。任何帮助将不胜感激。

#!/bin/bash

ROOTPATH="/Volumes/ARC-RAID/STORAGE/ASSET-Processing/Movies/LANDSCAPE/BRAND-RECOVERED/BRAND-RECOVERED-LANDSCAPE "
for subdir in *; do
  cd ${ROOTPATH}/${subdir}
  mkdir 00errors
  
  for path in *.{MOV,mov,MP4,mp4}; do

    ffmpeg -i "${path}" -f null -; echo$?
    RC=$?

    if [ "${RC}" -ne "0" ]; then
        # Do something to handle the error.
        mv ${path} ./00errors
    fi

  done
  cd ../
done

答案1

没有仔细查看您的代码,但建议您改用find

#!/bin/sh

topdir=/Volumes/ARC-RAID/STORAGE/ASSET-Processing/Movies/LANDSCAPE/BRAND-RECOVERED/BRAND-RECOVERED-LANDSCAPE

find "$topdir" -name 00error -prune -o \
    -type f \( -iname '*.mp4' -o -iname '*.mov' \) \
    ! -exec ffmpeg -i {} -f null /dev/null \; \
    -execdir mkdir -p 00error \; \
    -execdir mv -- {} 00error \;

或者,从以下位置调用一个简短的内联sh脚本find

#!/bin/sh

topdir=/Volumes/ARC-RAID/STORAGE/ASSET-Processing/Movies/LANDSCAPE/BRAND-RECOVERED/BRAND-RECOVERED-LANDSCAPE

find "$topdir" -name 00error -prune -o \
    -type f \( -iname '*.mp4' -o -iname '*.mov' \) -exec sh -c '
    for pathname do
        if ! ffmpeg -i "$pathname" -f null /dev/null; then
            dirpath=${pathname%/*}
            mkdir -p "$dirpath"/00error
            mv "$pathname" "$dirpath"/00error
        fi
    done' sh {} +

这两种变体都假设您有一个find能够理解-iname与文件名不区分大小写地匹配模式,并且它理解-execdir,它会在找到的文件的目录中执行实用程序。和都是非标准的-iname-execdir

这将拾取顶部目录下任何位置的任何电影文件,因此它对目录结构的要求不像脚本那么严格。


关于您的代码:

  • 我注意到 的值ROOTPATH末尾有一个空格。这可能是偶然的。

  • echo$?由于和之间缺少空格,将尝试执行类似echo0或类似的操作。echo1echo$?

  • 修复上述拼写错误将导致 shell$?用 的退出状态覆盖echo,因此$RC稍后不会反映 的退出状态ffmpeg,而是反映 的退出状态echo

  • 无需将命令的退出状态保存在单独的变量中,然后针对零进行测试,而是直接在语句中使用该命令if。我在上面命令的第二个变体中执行了此操作find

  • *可以匹配目录名称和非目录名称。因此,使用cd ${ROOTPATH}/${subdir}可能会失败(也可能由于目录名称中的空格而失败,例如目录末尾的空格ROOTPATH,或者由于目录为空)。如果cd失败,您的内部循环可能会处理错误的文件,并且进一步cd ..向下会使您的级别过高。

这是您的代码的更正变体:

#!/bin/bash

topdir=/Volumes/ARC-RAID/STORAGE/ASSET-Processing/Movies/LANDSCAPE/BRAND-RECOVERED/BRAND-RECOVERED-LANDSCAPE

# Make globbing case-insensitive (nocaseglob), and
# make patterns disappear if not matched (nullglob)
shopt -s nullglob nocaseglob

for subdir in "$topdir"/*/; do
    for mov in "$subdir"/*.{mov,mp4}; do
        if [ -f "$mov" ] && ! ffmpeg -i "$mov" -f null /dev/null; then
            mkdir -p "$subdir"/00error &&
            mv "$mov" "$subdir"/00error
        fi
    done
done

如您所见,cd没有必要。

没有内循环:

#!/bin/bash

topdir=/Volumes/ARC-RAID/STORAGE/ASSET-Processing/Movies/LANDSCAPE/BRAND-RECOVERED/BRAND-RECOVERED-LANDSCAPE

shopt -s nocaseglob nullglob

for mov in "$topdir"/*/*.{mov,mp4}; do
    if [ -f "$mov" ] && ! ffmpeg -i "$mov" -f null /dev/null; then
        mkdir -p "${mov%/*}"/00error &&
        mv "$mov" "${mov%/*}"/00error
    fi
done

相关内容