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

/path/to/music/directory/{**/,}*

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

{**/,}* 

part.

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

file -i "$@" |

to

file --mime-type "$@" | 

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

link|improve this question
feedback

2 Answers

up vote 0 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
before-a-after
before-bb-after
before-1-after
before-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/{**/,}*
/path/to/music/directory/**/*
/path/to/music/directory/*

Globstar

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
first/
first/aaa
first/second
first/second/bbb01
first/second/bbb02
first/second/third
first/second/third/ccc1
first/second/third/ccc2
first/second/third/ccc3

we could have the following expansions:

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

$ printf '%s\n' first/**/b*
first/second/bbb01
first/second/bbb02

$ printf '%s\n' first/**/c*
first/second/third/ccc1
first/second/third/ccc2
first/second/third/ccc3

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

link|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
feedback

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"
done

exit 0

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

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

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