2

This question already has an answer here:

#!/bin/bash

for a in ./*.flac; do
  ffmpeg -i "$a" -qscale:a 0 "${a[@]/%flac/mp3}"
done

I found this script a few days ago to convert all FLAC files in the current directory into the MP3 format.

What I don't understand here is the "${a[@]/%flac/mp3}" part. I think it replaces the ending flac with mp3 for the current filename. But what eactly does the [@] part do? Is it a regular expression?

marked as duplicate by jasonwryan, kenorb, grochmal, GAD3R, don_crissti Dec 19 '16 at 21:05

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • @jasonwryan Not a dupe. It's not %/ here, it's /% – xhienne Dec 19 '16 at 18:09
  • @xhienne it's all parameter expansion; so it is a duplicate... – jasonwryan Dec 19 '16 at 19:35
  • @jasonwryan Thanks for pointing me in the right direction. There are two very interesting links in that other question. – monkey2k Dec 19 '16 at 20:05
4

As you guessed it, ${var/%flac/mp3} replaces the ending "flac" (if any) in value $var with "mp3". "${var[@]/%flac/mp3}" would do the same on each element output by ${var[@]} if var was an array.

Here, since a is not an array, you can remove [@] (I assume this is an heritage from previous attempts by the programmer).

2

This does a simple shell expansion. The variable a will iterate through every file matching the *.flac glob.

Since each entry will be a file (and I'm presuming no spaces in the filenames), foo.flac will be the expansion of both $a and ${a[@]}.

The construct ${var/%foo/bar} will replace foo with bar at the end of a variable var. So it's replacing the extension flac with the extension mp3 in your example to provide ffmpeg with the output filename.

Not the answer you're looking for? Browse other questions tagged or ask your own question.