我有许多包含 .mp4 文件的文件夹。我编写了一个脚本,它获取 mp4 文件并将它们转换为每帧 1 个 jpeg 图像。重要的是,该脚本的输出(保留文件名,末尾附加 _frame 编号)进入一个新创建的文件夹,文件基名如下:
\n#!/bin/bash\nfor f in *.mp4; do mkdir -p "${f%.*}" && ffmpeg -i ${f} -start_number 000 "${f%.*}/${f}_%03d.jpg"; done\nRun Code Online (Sandbox Code Playgroud)\n我可以一次为每个父文件夹运行一个,没有问题,但我想只运行一次并让它递归运行。
\n我将代码更改为:
\n#!/bin/bash\nfor f in *.mp4/; do mkdir -p "${f%.*}" && ffmpeg -i ${f} -start_number 000 "${f%.*}/${f}_%03d.jpg"; done\nRun Code Online (Sandbox Code Playgroud)\n并尝试使用 mkdir 部分(通过添加 ./),但无论我做什么,我都会收到以下错误。
\nmkdir:无法创建目录 \xe2\x80\x98*\xe2\x80\x99:参数无效
\n我需要做什么才能允许 mkdir 在各自的子文件夹中创建适当的新文件夹?
\n文件结构如下:
\nparent folder\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 videos_1\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 videos_1_basename_1.mp4\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 videos_2_basename_2.mp4\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 videos_2\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 videos_2_basename_1.mp4\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 videos_2_basename_2.mp4\n.sh script\nRun Code Online (Sandbox Code Playgroud)\n
您可以使用globstarbash 选项在子目录中递归,也可以使用该nullglob选项将模式扩展为 null 而不是自身(错误的原因如另一个答案中所述):
#!/usr/bin/env bash
shopt -s globstar nullglob
for f in **/*.mp4; do
d=${f%.mp4}
b=$(basename -s.mp4 "$f")
if mkdir -p "$d"; then
ffmpeg -i "$f" -start_number 000 "$d/${b}_%03d.jpg"
else
printf 'could not mkdir %s\n' "$d"
fi
done
Run Code Online (Sandbox Code Playgroud)
注意:对于名为:
videos_1/videos_1_basename_1.mp4
Run Code Online (Sandbox Code Playgroud)
这将创建名为:的 JPEG 文件
videos_1/videos_1_basename_1/videos_1_basename_1_000.jpg
videos_1/videos_1_basename_1/videos_1_basename_1_001.jpg
...
Run Code Online (Sandbox Code Playgroud)
如果您确实想将扩展名保留.mp4在名称中:
videos_1/videos_1_basename_1/videos_1_basename_1.mp4_000.jpg
...
Run Code Online (Sandbox Code Playgroud)
只需删除-s.mp4的选项即可basename。