Ask Ubuntu is a question and answer site for Ubuntu users and developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have the same problem as was asked in question Rename Music Files with Missing File Extensions and I found the script provided by @Gilles very educational, but unfortunately it didn't work the way I expected. What I was looking for was a script that would add a file extension to all music files without extension in all subdirectories, at all levels, below "/path/to/music/directory/". The suggested command line parameter


makes the script go through all the files in the subdirectories one level below "/path/to/music/directory/" but not at levels below that. What command line parameter should I use to traverse all files at all levels below "directory/" ?

Would also appreciate a pointer to documentation for the



BTW, For those interested in the original answer. I found that the script works better after I changed the line

file -i "$@" |


file --mime-type "$@" | 

(If I had had the privilege level I would have given this as a comment in the original answer)

share|improve this question
up vote 1 down vote accepted

I think you have only to activate the bash globstar option, because it is not active by default in Ubuntu, as explained in the following.

The expression /path/to/music/directory/{**/,}* contain two expansion constructs: has a brace expansion and next a pathname expansion.

Brace expansion

Brace expansion is best explained with an example:

$ printf '%s\n' before-{a,bb,1,22}-after

(I've used, here and in the following, the command printf '%s\n' item1 item2 etc.. that is like echo but prints each element on a new line)

You see that each comma separated element in braces results in an expanded element.

The original example, containing in braces the elements **/ and an empty element, expands to

$ printf '%s\n' /path/to/music/directory/{**/,}*


Turn now to the bash glob **, that is mentioned two times in the bash manual page, both in relation to the shell option globstar, and the meaning is as follow:

the pattern ** used in a pathname expansion context will match a files and zero or more directories and subdirectories.

This shell option is not active by default in Ubuntu:

$ shopt globstar
globstar        off

You can activate it with

shopt -s globstar

(use shopt -u globstar to deactivate it).

If we have the following directory structure:

$ find first/ | sort

we could have the following expansions:

$ printf '%s\n' first/**/a*

$ printf '%s\n' first/**/b*

$ printf '%s\n' first/**/c*

so you can see that ** is able to expand to more than a pathname element.

share|improve this answer
Your assumption was right on. Enabling globstar made it work the way I wanted. Thanks for the explanation. – Andy Aug 1 '11 at 12:08

I would do something like this

#! /bin/bash

[[ -d "$1" ]] || { echo "$1 not a directory, exiting..."; exit 1; }

find "$1" -type f | while read F; do
  # do what you want with the "$F"

exit 0

and then invoke the script via ./my_script <directory>

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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