Другой вариант — отправить несколько команд на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
), команды:
/^host=
...$h
$
--начать поиск(/
)строки host=
в начале строки (^
), затем следует содержимое $h
и конец строки($
). Ослабьте требования к концу строки -из -, если ваш хост не полностью совпадает.
?^ip=
--Теперь, когда мы находимся на совпадающей строке, найдите текст ip=
в начале строки в обратном направлении.
c
--изменить эту строку
вставить текстip=new.ip.here
.
--конец текста вставки
w
--записать файл на диск
q
--уволился
Вызов ed с -s
отключает счетчик байтов -, который выдается при открытии и сохранении файла. Перенаправление всей команды на /dev/null
отключает вывод по умолчанию, когда ed
находит строки host=
и ip=
, которые мы ищем.
Не слишком внимательно изучая ваш код, но предлагая вместо этого использовать 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