У меня есть этот пакетный файл, который я использую в Windows, который я хотел бы перевести в сценарий Linux. Может ли кто-нибудь помочь с этим? Вот сценарий и попытка версии для Linux. Я этого не писал, мне кто-то помог.

Цель состоит в том, чтобы запустить команду python "manual.py", которая преобразует любой файл, который не является MP4, в MP4 с FFmpeg. У меня это работает как запланированная задача в Windows против сопоставленного общего ресурса Linux; Тем не менее, я бы предпочел просто запустить скрипт на Linux.  Мои навыки написания сценариев в Linux, ну, в общем, отсутствуют.

Это работает

@echo off
setlocal enableDelayedExpansion
Set Location="z:\movies"

Set PatternName=".*\.mp4 .*\srt"

Set Transcoder="c:\sysinternals\mp4auto\"

for /f "delims=" %%F in ('dir %Location% /s /b /a-d ^| findstr /v /i /e /r %PatternName%') do (%Transcoder%manual.py -i "%%F" -a
)

Это не так.

!#/bin/sh

Location="/TV Shows/*/*"
Pattern="*.mp4"
Transcode = /Mp4auto/manual.py

for Convert in (find $Location -type f \( -iname "*.*" ! -iname $Pattern \))
do

$Transcode -i $Convert -a
done

Что мне нужно сделать, чтобы это работало?

1 ответ1

1

Есть несколько вопросов:

  • Первые два символа сценария оболочки должны быть #! нет !#

Предполагая, что вы решили использовать оболочку типа POSIX (это хороший выбор):

  • При присвоении переменной не должно быть пробела до или после = .
  • Когда вы используете (ссылаетесь) на переменную, вы почти всегда должны помещать ее в кавычки.  (Мы часто говорим, что вы должны всегда заключать в кавычки переменные оболочки, если у вас нет веских причин не делать этого, и вы уверены, что знаете, что делаете.)
  • Вы запускаете команду find , берете ее вывод и используете ее как часть более крупной команды.  Вы помещаете команду find в круглые скобки.  Вы должны положить его в $() .
  • Но это плохой способ сделать это, и потерпит неудачу, если любые пути содержат пробелы.  И поэтому он взлетит до небес, потому что все ваши пути будут содержать пробелы, потому что ваше имя каталога - "/TV Shows" .

    Я вернусь к этому.

  • Первым аргументом для find обычно должно быть имя каталога.  Это является грубым упрощением - Есть много вариаций - но дело в том , что вы должны дать find аргумент "/TV Shows" - шоу».  Вам не нужно указывать "/TV Shows/*/*" ; команда find найдет все файлы в каталоге "/TV Shows" .
  • Если вы хотите посмотреть только два уровня каталогов, так и скажите.

Другие заметки:

  • В вашем BAT-файле используется шаблон. .*\srt .  Но вы не объяснили значение этого и не предприняли никаких попыток перевести его в свой сценарий оболочки.
  • Вы используете -iname "*.*" В вашей команде find в вашем скрипте.  Это соответствует всем файлам, которые имеют . в их именах.  (Этот символ известен как «точка», «точка» и «точка».)  Не все Unix-файлы имеют точку в своем имени, поэтому это не то же самое, что сопоставление всех файлов.  Это правильно, если вы хотите исключить файлы, у которых нет точек в именах.  Я указываю на это, потому что

    • Люди, переходящие из Windows, привыкли думать, что *.* Означает все файлы.
    • Люди, плохо знакомые с Unix (и find , в частности), иногда считают, что им нужно сказать -name "*" или что-то подобное, чтобы получить все файлы, а затем начать указывать исключения.  Это не нужно; find находит все файлы по умолчанию.
    • Вы не указали требование исключать файлы, у которых нет точек в именах.
  • Сценарий обрабатывает все файлы с точками в имени и не заканчивается на .mp4 .  Это может включать файлы .py , .txt и т.д.  Вероятно, безопаснее искать типы файлов, которые можно конвертировать в MP4.

Итак, если вы хотите переименовать свой каталог в TV_Shows и можете гарантировать, что ни одно из имен ваших файлов не будет содержать пробелов, тогда вам следует начать:

#!/bin/sh

Location="/TV_Shows"
Pattern="*.mp4"
Transcode=/Mp4auto/manual.py

for Convert in $(find "$Location" -type f \( -iname "*.*" ! -iname "$Pattern" \))
do
    "$Transcode" -i "$Convert" -a
done

Лучший подход, который обрабатывает имена путей, содержащие пробелы, заключается в использовании способности find запускать команду для каждого найденного файла:

#!/bin/sh

Location="/TV Shows"
Pattern="*.mp4"
Transcode=/Mp4auto/manual.py

find "$Location" -type f \( -iname "*.*" ! -iname "$Pattern" \) -exec "$Transcode" -i {} -a ';'

Вы можете разделить эту длинную команду на две строки с помощью \ (обратный слеш):

find "$Location" -type f \( -iname "*.*" ! -iname "$Pattern" \) \
                        -exec "$Transcode" -i {} -a ';'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .