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

Bash脚本使用数组批量转换多格式视频至MKV的故障排查与解决诉求

Fixing Multi-Format Video Conversion in Your Bash Script

Hey there! Let's get your script working properly for batch-converting multiple video formats to MKV. The issue you're hitting is all about how Bash expands arrays and wildcards—let's break it down and fix it step by step.

What's Going Wrong

When you use *.${auto_ext[*]}, Bash expands that to something like *.avi mp4 m4p m4v ...—so your for loop treats each of those as a separate filename instead of combining them into wildcard patterns for each format. That's why you're getting errors about files like mp4 not existing (it's trying to open a file literally named mp4, not files ending with .mp4).

Quick note on [*] vs [@]:

  • "${auto_ext[*]}" joins all array elements into a single string, separated by your system's IFS (usually a space).
  • "${auto_ext[@]}" treats each array element as a separate, quoted string—this is what you want for looping through individual formats.

The Fix

We need to loop through each format in your array, generate a wildcard pattern for each (like *.avi, *.mp4), and process the matching files. We'll also add a couple of quality-of-life improvements:

  1. Use nullglob to avoid errors when a format has no matching files (Bash will just skip that pattern instead of passing *.ext as a literal filename).
  2. Redirect error output to /dev/null to suppress "file not found" noise for formats with no files.

Updated Script

Here's your modified script with these fixes:

#!/bin/bash
# Enable nullglob to skip wildcard patterns that match no files
shopt -s nullglob

auto_ext=(avi mp4 m4p m4v webm mpg mp2 mpeg mpe mpv ogg wmv mov qt)

menu_option_one() {
    echo ""
    echo ""
    echo -n " Enter file extension of file to convert: "
    read extension
    for f in *.$extension; do 
        mkvmerge -o "${f%}.mkv" "$f" 2>/dev/null
    done
}

menu_option_two() {
    # Loop through each extension in the array
    for ext in "${auto_ext[@]}"; do
        # Process all files with this extension
        for f in *.$ext; do
            mkvmerge -o "${f%}.mkv" "$f" 2>/dev/null
        done
    done
}

menu_option_three() {
    echo ""
    echo ""
    echo -n " Enter file extension of file to convert: "
    read extension
    for f in *.$extension; do 
        ffmpeg -i "$f" "${f%}.mkv" 2>/dev/null
    done
}

menu_option_four() {
    # Loop through each extension in the array
    for ext in "${auto_ext[@]}"; do
        # Process all files with this extension
        for f in *.$ext; do
            ffmpeg -i "$f" "${f%}.mkv" 2>/dev/null
        done
    done
}

press_enter() {
    unset auto_ext
    unset extension
    echo ""
    echo -n " Press Enter to continue... "
    read
    clear
}

incorrect_selection() {
    echo "Incorrect selection! Try again."
}

until [ "$selection" = "0" ]; do
    clear
    echo ""
    echo " This file converts video files to mkv in the current directory only... "
    echo ""
    echo " 1 - Use mkvmerge (fastest, decent quality)"
    echo " 2 - Autoconvert all files using mkvmerge"
    echo " 3 - Use ffmpeg (slowest, best quality)"
    echo " 4 - Autoconvert all files using ffmpeg"
    echo " 0 - Exit"
    echo ""
    echo -n " Enter selection: "
    read selection
    echo ""
    case $selection in
        1 ) clear ; menu_option_one ; press_enter ;;
        2 ) clear ; menu_option_two ; press_enter ;;
        3 ) clear ; menu_option_three ; press_enter ;;
        4 ) clear ; menu_option_four ; press_enter ;;
        0 ) clear ; exit ;;
        * ) clear ; incorrect_selection ; press_enter ;;
    esac
done

exit 0

Key Changes Explained

  • shopt -s nullglob: This tells Bash to remove wildcard patterns that don't match any files, so you won't get errors for formats with no videos in the directory.
  • Nested loops in menu_option_two and menu_option_four: First we loop through each extension in auto_ext, then for each extension, we loop through all matching files. This ensures we correctly target every file with the specified formats.
  • 2>/dev/null: Redirects error messages (like "file not found" or conversion warnings) to the null device, keeping your output clean.

Now when you run option 2 or 4, the script will process all files matching any format in your auto_ext array—no more manual input required, and you can easily add new formats to the array whenever you need!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:51:23