From jzitt at josephzitt.com Sun Jan 1 22:12:33 2006 From: jzitt at josephzitt.com (Joseph Zitt) Date: Sun, 01 Jan 2006 22:12:33 -0800 Subject: [buug] Spaces within filenames in a bash script Message-ID: <43B8C451.6020700@josephzitt.com> Hi, all. This would seem to be an FAQ, but I haven't been quite able to get it to work after a lot of experimenting and digging around. I'm using a bash script that I got from an article on an O'Reilly site to convert FLAC files to mp3s. (I'm guessing that it could easily be tweaked to do oggs, but the problem would be the same.) It's blowing up badly on files with spaces in the names: #!/bin/bash FILES=$(ls *.flac | cut -d '.' -f1) for i in $FILES; do echo converting: $i.flac flac -sdc $i.flac | lame - $i.mp3 done I've tried all sorts of different incantations, mostly throwing quotation marks in to see what would work, but no matter what I do, it takes a filename like "foo bar baz.flac" and treats it as three files, "foo", "bar", and "baz.flac". Can someone suggest a tweak that will handle this (other than renaming the files to start with, which would be even more of a hassle)? Thanks for any enlightenment. From brian at dessent.net Mon Jan 2 02:00:09 2006 From: brian at dessent.net (Brian Dessent) Date: Mon, 02 Jan 2006 02:00:09 -0800 Subject: [buug] Spaces within filenames in a bash script References: <43B8C451.6020700@josephzitt.com> Message-ID: <43B8F9A9.630A0C3A@dessent.net> Joseph Zitt wrote: > #!/bin/bash > FILES=$(ls *.flac | cut -d '.' -f1) > for i in $FILES; do > echo converting: $i.flac > flac -sdc $i.flac | lame - $i.mp3 > done You should consider using find instead of ls. And it looks like what you have would die if you had a filename with more than one "." in it. # untested find . -name \*.flac | while read F; do echo "converting: $F" flac -sdc "$F" | lame - "$(basename "$F" .flac).mp3" done By the way, just for simple commands the best way to do this is: find /path -name \*.whatever -print0 | xargs -0 command ...which will handle filenames with spaces, quotes, tabs, newlines, and anything else. Brian From Michael.Paoli at cal.berkeley.edu Mon Jan 9 01:23:58 2006 From: Michael.Paoli at cal.berkeley.edu (Michael Paoli) Date: Mon, 9 Jan 2006 01:23:58 -0800 Subject: [buug] Spaces within filenames in a bash script In-Reply-To: <43B8C451.6020700@josephzitt.com> References: <43B8C451.6020700@josephzitt.com> Message-ID: <1136798638.43c22bae226cb@webmail.rawbw.com> Quoting Joseph Zitt: > tweaked to do oggs, but the problem would be the same.) It's blowing up > badly on files with spaces in the names: > > #!/bin/bash > FILES=$(ls *.flac | cut -d '.' -f1) > for i in $FILES; do > echo converting: $i.flac > flac -sdc $i.flac | lame - $i.mp3 > done You could try something roughly like: #!/bin/sh unset ret for flac in *.flac do if [ -f "$flac" ]; then #exists as ordinary file (or symlink to ordinary file) echo "$0: converting: $flac" b="`basename "$flac" .flac`" flac -sdc -- "$flac" | lame - -- "$b".mp3 && ret="${ret-0}" else if [ X'*.flac' != X"$flac" ] || >>/dev/null 2>&1 ls -d "$flac"; then #not an ordinary file 1>&2 echo "$0: skipping $flac: not a file" fi ret=1 fi done exit "$ret" I also made some presumptions about flac and lame taking -- to indicate end of all options - this tends to be generally true with most newer UNIX/LINUX commands, but isn't necessarily supported on all commands. Carefully study the man page stuff (e.g. bash(1) or sh(1)), paying particular attention to various forms of quoting and command substitution (and how they also interact). Lots of stuff stuck in articles, web sites, etc., are probably more often meant for or more useful for general illustrative examples, rather than particularly robust and complete code examples (this is often particularly the case in print when space may be at a premium). Of course lots of folks also write less than wonderfully robust code. The example bit I did, above, is also just for illustrative purposes :-). It certainly makes some improvements, but it doesn't handle everything ideally, e.g. ideally if flac failed (e.g. exited non-zero) that should cause the script to return a non-zero value when it completes. references/excerpts: bash(1) basename(1) http://home.comcast.net/~j.p.h/cus-faq-2.html#11 http://www.rawbw.com/~mp/unix/sh/