Using basename in a command run with find -exec

Forum rules
Before you post please read how to get help
Post Reply
BreadTed
Level 1
Level 1
Posts: 3
Joined: Sat Jan 14, 2017 3:33 pm

Using basename in a command run with find -exec

Post by BreadTed » Sun Jun 24, 2018 5:43 am

What I want to do is convert a whole collection of wav files to mp3 files.

I am trying to follow an answer given in https://stackoverflow.com/questions/216 ... -in-a-loop , namely,

find ./ -name "*.wav" -exec ffmpeg -i "{}" -ab 320k -ac 2 '$(basename {} wav)'.mp3 \;

and the basename business is giving me a right headache. It is clearly not working properly as I get (e.g. for the song "07 Brakes On.wav") the error:

$(basename ./07 Brakes On.wav wav).mp3: No such file or directory

So the basename is not executing but am at a loss as to how it can be fixed. Doing it in a loop seems to have its own problems.

Alternative suggestions for batch mp3 conversions also welcome, I just want to get it done!

BreadTed
Level 1
Level 1
Posts: 3
Joined: Sat Jan 14, 2017 3:33 pm

Re: Using basename in a command run with find -exec

Post by BreadTed » Sun Jun 24, 2018 5:53 am

I should add, I'm using Mint 18.2, and the music files are on a mounted network drive.

But I think the main problem is that I cannot get my head around the proper use of dollar signs, single and double quotes, brackets, etc etc.

User avatar
xenopeek
Level 24
Level 24
Posts: 22464
Joined: Wed Jul 06, 2011 3:58 am
Location: The Netherlands

Re: Using basename in a command run with find -exec

Post by xenopeek » Sun Jun 24, 2018 6:04 am

Two minor problems with your command:
- the filename argument to basename should be quoted, as it may contain spaces
- and I think the suffix argument to basename should start with a dot (this may possibly work, but that is what basename examples do)

The major problem is the substitute command $(..) only works when running a shell. You're running find, which doesn't know about shell substitute commands :) So if you want to use that as argument for find's exec you need to do that by having find execute a shell that executes your command.

Putting it all together it would be something like:
find . -name \*.wav -exec bash -c 'ffmpeg -i "{}" -ab 320k -ac 2 "$(basename "{}" .wav).mp3"' \;
Image

gm10
Level 5
Level 5
Posts: 634
Joined: Thu Jun 21, 2018 5:11 pm

Re: Using basename in a command run with find -exec

Post by gm10 » Sun Jun 24, 2018 7:35 am

Is the basename really intended though, i.e. do you want to drop the subfolders? Just going by the example name you provided I'm thinking you'd end up with quite a mess doing it that way.

rene
Level 7
Level 7
Posts: 1805
Joined: Sun Mar 27, 2016 6:58 pm

Re: Using basename in a command run with find -exec

Post by rene » Sun Jun 24, 2018 9:45 am

The good point one up can be worked around with use of -execdir rather than -exec but alternatively...

find -exec syntax is a bit of a disaster even for experienced command line users: a trick I oft use and generally suggest is launching /bin/bash with the filename as a parameter:

Code: Select all

find ... -exec /bin/bash -c '...' -- \{} \;
This provides you with full bash possibilities for the bit between single quotes, which receives the filename as its "$1". I.e., in your case you could use

Code: Select all

find -name "*.wav" -exec /bin/bash -c 'ffmpeg -i "$1" -ab 320k -ac 2 "${1%%.wav}.mp3"' -- \{} \;
This also takes the opportunity to use the bash parameter expansion ${parameter%%word} syntax to replace ".wav" with ".mp3" (see the bash manpage) rather than basename but that bit's not primary. Exec'ing /bin/bash with the filename as parameter is: it provides for significantly better syntax/control.

BreadTed
Level 1
Level 1
Posts: 3
Joined: Sat Jan 14, 2017 3:33 pm

Re: Using basename in a command run with find -exec

Post by BreadTed » Mon Jun 25, 2018 2:48 pm

Thanks for the replies. I took xenopeek's answer (it was the only one there at the time!), using execdir instead of exec after noticing the problem on a set of test files (pats self on back).

It didn't like a couple of files which had backticks in the title but I just did those manually. Although it did take me a while to cd into a folder which also had a backtick in its name...

And while I was waiting for the converting to finish, I even wrote a little script to work out the progress :D

Post Reply

Return to “Scripts & Bash”