翻译 Windows 脚本以在 Linux 中使用

翻译 Windows 脚本以在 Linux 中使用

我有这个在 Windows 中使用的批处理文件,我想将其转换为 Linux 脚本。有人能帮忙吗?这是脚本和 Linux 版本的尝试。这不是我写的,是有人帮助我的。

目的是运行一个 Python 命令“manual.py”,该命令使用 FFmpeg 将任何非 MP4 文件转换为 MP4。我已将其作为计划任务在 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

有几个问题:

  • Shell 脚本的前两个字符应该是#!, 而不是!#

假设您选择使用 POSIX 类型的 shell(这是一个不错的选择):

  • 分配给变量时, 之前或之后不能有空格=
  • 当你使用參考) 变量,您几乎总是应该将其放在引号中。(我们经常说,除非您有充分的理由不这样做,否则您应该始终引用 shell 变量,并且您当然你知道你在做什么。
  • 您正在运行该find命令,并获取其输出并将其用作更大命令的一部分。您将该find命令放在括号中。您需要将其放入$()
  • 但这不是一种好方法,如果任何路径名包含空格,就会失败。所以它会飞得很高,因为全部您的路径名将包含空格,因为您的目录名是"/TV Shows"

我会回过头来谈这个问题。

  • 的第一个参数find通常应该是目录的名称。这是一个过于简单的说法 — 有很多变体 — 但重点是您应该给出find 一个参数"/TV Shows"。您不需要指定"/TV Shows/*/*"find将查找"/TV Shows"目录下的所有文件。
  • 如果您只想查看两级目录,请这么说。

其他说明:

  • 您的 BAT 文件使用了该.*\srt模式。但您没有解释这一点的重要性,也没有尝试将其翻译成您的 shell 脚本。

  • 您可以在 shell 脚本中使用命令。这将匹配所有-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 ';'

我刚刚注意到原帖者问了一个后续问题:

你能给我举个例子,如何转换任何以 .mkv 或 .avi 为扩展名的文件吗?

在 中使用-o,表示“或” find


Pattern1="*.mkv"
Pattern2="*.avi"

find "$Location" -type f \( -iname "$Pattern1" -o -iname "$Pattern2" \) \
                        -exec "$Transcode" -i {} -a ';'

相关内容