1

我目前正在使用 bash shell 脚本使用 FFMPEG 将我的所有 Plex DVR 录音编码为 H.264。我正在使用我在网上找到的这个小 for 循环来编码单个目录中的所有文件:

for i in *.ts;
    do echo "$i" && ffmpeg -i "$i" -vf yadif -c:v libx264 -preset veryslow -crf 22 -y "/mnt/d/Video/DVR Stash/Seinfeld/${i%.*}.mp4";
done

这很好地达到了目的,但在此过程中,我想将文件重命名为我喜欢的命名约定,以便在编码文件中将原始文件名Seinfeld (1989) - S01E01 - Pilot.ts重命名为。Seinfeld S01 E01 Pilot.mp4虽然我已经在使用正则表达式将.ts扩展名更改为.mp4,但我不是正则表达式的专家,尤其是在 bash shell 中,因此我们将不胜感激。

对于任何对我的 Plex 设置感兴趣的人,我使用一台运行 Linux Mint 的旧机器作为我的专用 DVR,并使用我的日常驱动程序(游戏机)通过网络实际访问它,因此视频编码的处理能力更强。虽然那是一台 Windows 机器,但我使用 WSL2 下的 Ubuntu bash 来运行我的脚本,因为我更喜欢它而不是 Windows 命令提示符或 Powershell(我的日常工作是公司发行的 Mac 上的网络开发人员)。所以这是我的代码示例,供任何可能考虑做类似事情的人使用。

if [[ -d "/mnt/sambashare/Seinfeld (1989)" ]]
then
    cd "/mnt/sambashare/Seinfeld (1989)"
    echo "Seinfeld"
    for dir in */; do
        echo "$dir/"
        cd "$dir"
        for i in *.ts;
            do echo "$i" && ffmpeg -i "$i" -vf yadif -c:v libx264 -preset veryslow -crf 22 -y "/mnt/d/Video/DVR Stash/Seinfeld/${i%.*}.mp4";
        done
        cd ..
    done
fi

虽然我考虑过为所有节目做一个 for 循环,但现在我正在单独做每个节目,因为有一些节目我有自定义编码设置

4

1 回答 1

1

使用extglob对您的代码进行小修改,类似这样

#!/usr/bin/env bash

if [[ -d "/mnt/sambashare/Seinfeld (1989)" ]]; then
  cd "/mnt/sambashare/Seinfeld (1989)" || exit
  echo "Seinfeld"
  for dir in */; do
    echo "$dir/"
    cd "$dir" || exit
    for i in *.ts; do
      shopt -s extglob
      new_file=${i//@( \(*\)|- )}
      new_file=${new_file/E/ E}
      new_file=${new_file%.*}
      echo "$i" &&
      ffmpeg -i "$i" -vf yadif -c:v libx264 -preset veryslow -crf 22 -y "/mnt/d/Video/DVR Stash/Seinfeld/${new_file}.mp4"
      shopt -u extglob
    done
    cd ..
  done
fi

E如果在剧集之外的某个地方的文件名中有/是,则字符串/glob/模式切片可能会失败。


使用扩展正则表达式BASH_REMATCH的运算符。=~即使E文件名中有更多 's,这也将起作用。

#!/usr/bin/env bash

if [[ -d "/mnt/sambashare/Seinfeld (1989)" ]]; then
  cd "/mnt/sambashare/Seinfeld (1989)" || exit
  echo "Seinfeld"
  for dir in */; do
    echo "$dir/"
    cd "$dir" || exit
    for i in *.ts; do
       regex='^(.+) (\(.+\)) - (S[[:digit:]]+)(E[[:digit:]]+) - (.+)([.].+)$'
       [[ $i =~ $regex ]] &&
       new_file="${BASH_REMATCH[1]} ${BASH_REMATCH[3]} ${BASH_REMATCH[4]} ${BASH_REMATCH[5]}"
      echo "$i" &&
      ffmpeg -i "$i" -vf yadif -c:v libx264 -preset veryslow -crf 22 -y "/mnt/d/Video/DVR Stash/Seinfeld/${new_file}.mp4"
    done
    cd ..
  done
fi
  • 添加了一个cd ... || exit只是为了确保脚本在尝试cd到某个地方时出现错误时停止/退出,而不是继续执行脚本。
于 2021-07-11T03:28:46.397 回答