Сканирование вложенных папок с помощью сценария BASH ${ROOTPATH}/${subdir}

Другой вариант — отправить несколько команд наed:

h=c
ed -s file <<< $'/^host='"${h}"$'$\n?^ip=\nc\nip=new.ip.here\n.\nw\nq' > /dev/null

Основная идея состоит в том, чтобы отредактировать файл и конвейер в разделенном новой строке -списке команд (в двух строках кавычек ANSI C $'... '), которые ищут данный хост (в переменной $h), затем выполните поиск строки, начинающейся с ip=, затем измените эту строку на что-то новое, затем сохраните и закройте ed. Разделенные символами новой строки (\n), команды:

  1. /^host=...$h$--начать поиск(/)строки host=в начале строки (^), затем следует содержимое $hи конец строки($). Ослабьте требования к концу строки -из -, если ваш хост не полностью совпадает.

  2. ?^ip=--Теперь, когда мы находимся на совпадающей строке, найдите текст ip=в начале строки в обратном направлении.

  3. c--изменить эту строку

  4. вставить текстip=new.ip.here

  5. .--конец текста вставки

  6. w--записать файл на диск

  7. q--уволился

Вызов ed с -sотключает счетчик байтов -, который выдается при открытии и сохранении файла. Перенаправление всей команды на /dev/nullотключает вывод по умолчанию, когда edнаходит строки host=и ip=, которые мы ищем.

0
02.03.2021, 02:57
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или echo1или что-то подобное из-за отсутствия пробела между echoи $?.

  • Исправление вышеуказанной опечатки приведет к тому, что оболочка перезапишет $?статусом выхода 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
0
18.03.2021, 22:27

Теги

Похожие вопросы