Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

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)

share|improve this question
add comment

2 Answers 2

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
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.

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
add comment

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>

share|improve this answer
add comment

Your Answer

 
discard

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.