问题描述
我目前正在使用 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 上的 Web 开发人员)。所以这是我的代码示例,供任何可能考虑做类似事情的人使用。
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 循环,但现在我正在单独做每个节目,因为有一些节目我有自定义编码设置
解决方法
对您的代码进行小修改,类似这样,带有 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/pattern 切片可能会失败。
使用 BASH_REMATCH
将 =~
运算符用于扩展正则表达式。即使文件名中有更多 E
,这也能正常工作。
#!/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
到某处而不是继续脚本时出现错误时脚本停止/退出。