Разрешение echo отказано (пытаясь использовать echo вместо команды ls в скрипте оболочки)

Предполагая, что файлы, вероятно, не буквально называются «File 1.mp4» и «Sub 1.srt» (хотя сценарий все еще работает, если они есть), но что числа в обоих наборы файлов совпадают:

#! /bin/sh

dir1='./dir1'
dir2='./dir2'

find "$dir1" -maxdepth 1 -name '*.mp4' | while IFS= read f ; do
    num=$(echo "$f" | sed -e 's/^.* \([0-9]\+\)\.mp4/\1/')
    subtitle=$(find "$dir2" -maxdepth 1 -name "* $num.srt" | head -1)
    if [ -n "$subtitle" ] ; then
        bn=$(basename "$f" .mp4)
        mv "$subtitle" "$dir2/$bn.srt"
    fi
done

Примечание: это будет работать для всех файлов, кроме тех, в имени которых есть символы новой строки. head -1 предназначен для предотвращения сбоя сценария, если окажется, что существует более одного файла .srt с одинаковым номером ... в этой ситуации первый найденный файл будет переименован, а другой (s) игнорируются.

Если вы хотите, чтобы субтитры были перемещены в тот же каталог, что и файлы .mp4, измените строку mv на:

mv "$subtitle" "$dir1/$bn.srt"
1
16.11.2018, 02:16
3 ответа

Кажется, вы хотите запросить carrierфайлы в /sys/class/net/*/, чтобы узнать, есть ли хотя бы один, указывающий, находитесь ли вы в сети или нет, (игнорируя*/lo/carrier).

С петлей-раковиной:

#!/bin/sh

online=0
for carrier in /sys/class/net/*/carrier; do
    case "$carrier" in
        */lo/carrier) continue ;;
    esac

    if read online <"$carrier" && [ "$online" -eq 1 ]; then
        break
    fi
done

if [ "$online" -ne 1 ]; then
    echo 'not online' >&2
    exit 1
fi

Использованиеbash:

#!/bin/bash

shopt -s extglob

online=0
for carrier in /sys/class/net/!(lo)/carrier; do
    if read online <"$carrier" && [ "$online" -eq 1 ]; then
        break
    fi
done

if [ "$online" -ne 1 ]; then
    echo 'not online' >&2
    exit 1
fi

Или, как bash"почти -один -лайнер"

#!/bin/bash

shopt -s extglob

grep -qx 1 /sys/class/net/!(lo)/carrier || ! echo not online >&2

Последнее предполагает, что файлы содержат одну цифру 1, если этот носитель находится в сети и что нет данных, или, по крайней мере, нет 1, если это не так.

Циклы выше (с использованиемread)будут считывать только первую строку из каждого файла carrier, пока не будет найден файл 1.


Проблема в вашем коде заключается в подстановке команд $(/sys/class/net/*), которая попытается выполнить первое совпадающее имя файла как команду с другими совпадающими именами файлов в качестве аргументов.

Кроме того, проверка [ $OnLine ]будет "истинной", если $OnLineне является -пустым. Я не уверен, что содержат файлы, которые вы анализируете, если носитель не находится в строке -, но даже ноль здесь будет восприниматься как «истина».

4
27.01.2020, 23:23

Как насчет этих -вкладышей. т. е. grepспециально исключил петлю.

Группа GNU

Примечание :требует GNUgrepот марта 2001 г. или более поздней версии . В частности, не работает с BusyBox grep, входящим в состав OpenWRT.

grep -q --exclude '/sys/class/net/lo/carrier' 1 /sys/class/net/*/carrier || echo "not online" >&2

Решение подходит для старых версий GNU grep и не -GNU grep

напр. Версии BusyBox.

grep -x 1 /dev/null /sys/class/net/*/carrier|grep -qv /lo/ || ! echo 'not online' >&2
1
27.01.2020, 23:23

вы можете попробовать выполнить указанный выше скрипт в режиме sudo

$судо су

"выполните здесь свой скрипт"

-2
27.01.2020, 23:23

Теги

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