You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本生成的PNG文件名含?4,如何提取视频名中的首个数字?

Fixing the Issue of Extracting the First Number from Video Filenames in Your Bash Script

Hey there, let's sort out this filename problem you're having. The issue with your current script is that grep -o -E '[0-9]+' matches all sequences of digits in the filename—including the 4 from .mp4. Since grep -o prints each match on a new line, your number variable ends up holding two values separated by a newline (like 1 and 4), which shows up as ? in the final PNG filename.

Here are a few ways to fix this and only grab the first set of digits from your video filenames:

Option 1: Tweak the grep Command to Get Only the First Match

Modify the line where you extract the number to keep just the first match from grep:

number=$(echo "$i" | grep -o -E '[0-9]+' | head -n 1)

The head -n 1 command will take only the first line of grep's output, which is the number from your video filename (e.g., 1 from video1.mp4), ignoring the 4 from .mp4.

Option 2: Use Bash Built-in String Handling (More Efficient)

Instead of calling an external tool like grep, you can use Bash's built-in features to extract the number—this is faster and avoids extra processes.

If your video filenames only have single-digit numbers (like video1.mp4, video2.mp4), you can do:

number=${i//[^0-9]/}  # Remove all non-digit characters
number=${number:0:1}  # Keep only the first character (the video number)

If you might have multi-digit numbers (like video123.mp4), use a regex match directly in Bash:

if [[ $i =~ ([0-9]+) ]]; then
    number=${BASH_REMATCH[1]}
fi

This captures the first continuous sequence of digits, so it'll never pick up the 4 from .mp4.

Full Modified Script

Here's the complete script using the regex match method (my recommendation for flexibility):

for i in *.mp4; do
    [ -f "$i" ] || break
    if [[ $i =~ ([0-9]+) ]]; then
        number=${BASH_REMATCH[1]}
        name="frame${number}.png"
        ffmpeg -i "$i" -ss 00:01:00.000 -vframes 1 "$name"
    fi
done

Bonus Tips

  • To make ffmpeg run quietly (without all the banner and debug output), add -hide_banner -loglevel error to the command:
    ffmpeg -hide_banner -loglevel error -i "$i" -ss 00:01:00.000 -vframes 1 "$name"
    
  • If you want to process videos in numerical order (instead of the default filename sort), you can use:
    for i in $(ls -v *.mp4); do
        # Same processing logic as above
    done
    
    The ls -v command sorts filenames in "version order", so video1.mp4 comes before video10.mp4.

内容的提问来源于stack exchange,提问作者Duck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:20:45