编写批处理脚本:匹配同文件夹同名异扩展名文件并执行对应FFmpeg脚本
Got it, let's work through this file matching task for your same-folder scenario. First, let's confirm your file set to make sure I'm aligned:
file01.jpg file01.wav file02.jpg file03.jpg file04.jpg file04.wav
You want to run three different scripts based on whether a base filename (without extension) has both a .jpg and .wav, only a .wav, or only a .jpg. Here's a practical, shell-based solution that's easy to adapt:
Approach 1: Basic Loop & Check (Works in All Bash Versions)
This method uses simple loops and file existence checks, so it's compatible with older bash versions.
Step 1: Collect Base Filenames
First, we'll extract all unique base names from .jpg and .wav files:
# Grab all base names from jpg files (strip .jpg) jpg_bases=$(for f in *.jpg; do echo "${f%.jpg}"; done) # Grab all base names from wav files (strip .wav) wav_bases=$(for f in *.wav; do echo "${f%.wav}"; done)
Step 2: Process Matching Pairs (Run script1)
Loop through .jpg bases and check if a corresponding .wav exists. If so, run script1 and mark the base as processed:
processed_bases="" for base in $jpg_bases; do if [ -f "$base.wav" ]; then echo "Executing script1 for matched pair: $base.jpg + $base.wav" ./script1 "$base.jpg" "$base.wav" # Track processed bases to avoid rechecking processed_bases="$processed_bases $base" fi done
Step 3: Process WAVs Without Matching JPG (Run script2)
Loop through .wav bases and check if they weren't processed (meaning no matching .jpg exists):
for base in $wav_bases; do if ! echo "$processed_bases" | grep -q "\b$base\b"; then echo "Executing script2 for orphaned WAV: $base.wav" ./script2 "$base.wav" fi done
Step 4: Process JPGs Without Matching WAV (Run script3)
Finally, loop through .jpg bases and check if they weren't processed (no matching .wav):
for base in $jpg_bases; do if ! echo "$processed_bases" | grep -q "\b$base\b"; then echo "Executing script3 for orphaned JPG: $base.jpg" ./script3 "$base.jpg" fi done
Approach 2: Associative Arrays (Cleaner for Bash 4+)
If you're using bash 4 or newer, associative arrays let you track file types per base name more efficiently:
# Declare an associative array to map base names to their file types declare -A file_map # Populate the array with .jpg entries for f in *.jpg; do base="${f%.jpg}" file_map["$base"]+="jpg " done # Populate the array with .wav entries for f in *.wav; do base="${f%.wav}" file_map["$base"]+="wav " done # Iterate through each base name and run the right script for base in "${!file_map[@]}"; do file_types=${file_map["$base"]} if [[ $file_types == *"jpg"* && $file_types == *"wav"* ]]; then # Both file types exist: run script1 ./script1 "$base.jpg" "$base.wav" elif [[ $file_types == *"wav"* ]]; then # Only WAV exists: run script2 ./script2 "$base.wav" elif [[ $file_types == *"jpg"* ]]; then # Only JPG exists: run script3 ./script3 "$base.jpg" fi done
Key Tips
- The
${f%.ext}syntax is a bash shortcut to remove the shortest suffix matching.extfrom a filename—perfect for getting the base name. - For the associative array method, make sure your bash version is 4+ (check with
bash --version). - Ensure your scripts (
script1,script2,script3) are executable (runchmod +x script1 script2 script3) and accept the file arguments if needed.
内容的提问来源于stack exchange,提问作者markb

