FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Debian > Debian User

 
 
LinkBack Thread Tools
 
Old 01-04-2010, 07:30 PM
Foss User
 
Default Handle each file at a time in loop?

$ ls
convert.sh Track 1.wav Track 3.wav Track 5.wav Track 7.wav Track 9.wav
Track 1.mp3 Track 2.wav Track 4.wav Track 6.wav Track 8.wav

So, you can see there are file names with spaces in them. I have
written a script like this to handle one file name at a time.

for file in `ls *.wav`
do
echo $file
done

Of course, this doesn't do what I need. The names are split wherever
there are spaces.

$ sh convert.sh
Track
1.wav
Track
2.wav
Track
3.wav
Track
4.wav
Track
5.wav
Track
6.wav
Track
7.wav
Track
8.wav
Track
9.wav

What is the right way to do this?


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
 
Old 01-04-2010, 07:34 PM
Tyler MacDonald
 
Default Handle each file at a time in loop?

Foss User <fossist@gmail.com> wrote:
> $ ls
> convert.sh Track 1.wav Track 3.wav Track 5.wav Track 7.wav Track 9.wav
> Track 1.mp3 Track 2.wav Track 4.wav Track 6.wav Track 8.wav
>
> So, you can see there are file names with spaces in them. I have
> written a script like this to handle one file name at a time.
>
> for file in `ls *.wav`
> do
> echo $file
> done
>
> Of course, this doesn't do what I need. The names are split wherever
> there are spaces.

Since you're in shell, it will do the expansion for you;

for file in *.wav
do
echo $file
done

When actually working with the filenames, make sure you encase the
variable name in double quotes so they dont get split up on the commandline;

for file in *.wav
do
newfile=$(echo "$file" | sed -e "s,foo,bar,g")
mv -v "$file" "$newfile"
done

Cheers,
Tyler


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
 
Old 01-04-2010, 07:36 PM
Rick Pasotto
 
Default Handle each file at a time in loop?

On Tue, Jan 05, 2010 at 02:00:31AM +0530, Foss User wrote:
> $ ls
> convert.sh Track 1.wav Track 3.wav Track 5.wav Track 7.wav Track 9.wav
> Track 1.mp3 Track 2.wav Track 4.wav Track 6.wav Track 8.wav
>
> So, you can see there are file names with spaces in them. I have
> written a script like this to handle one file name at a time.
>
> for file in `ls *.wav`
> do
> echo $file
> done
>
> Of course, this doesn't do what I need. The names are split wherever
> there are spaces.

The ls is a totally unnecessary extra process and is what is causing
your problem.

for file in *.wav
do
echo "$file"
done

The quote marks around the variable ensure it is treated as a unit even
if it contains spaces.

--
The demands of the socialists raise another question, which I have
often addressed to them, and to which, as far as I know, they have
never replied. Since the natural inclinations of mankind are so
evil that its liberty must be taken away, how is it that the
inclinations of the socialists are good? Are not the legislators
and their agents part of the human race? Do they believe
themselves moulded from another clay than the rest of mankind?
-- Frédéric Bastiat (1801-1850)
Rick Pasotto rick@niof.net http://www.niof.net


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
 
Old 01-04-2010, 10:13 PM
Alex Samad
 
Default Handle each file at a time in loop?

On Tue, Jan 05, 2010 at 02:00:31AM +0530, Foss User wrote:
> $ ls

[snip]

>
> Of course, this doesn't do what I need. The names are split wherever
> there are spaces.
if you want to work with spaces in shell scripts have a look at IFS (man
bash sh dash) the trick is

SAVEIFS="$IFS"
IFS="
"

<do some work>

IFS="$IFS"

note the IFS= across 2 lines is correct

[snip]

>
> What is the right way to do this?
>
>

--
"I mean, there was a serious international effort to say to Saddam Hussein, you're a threat. And the 9/11 attacks extenuated that threat, as far as I�concerned."

- George W. Bush
12/12/2005
Philadelphia, PA
 
Old 01-05-2010, 02:30 PM
"Boyd Stephen Smith Jr."
 
Default Handle each file at a time in loop?

In <3f8297b21001041230y69f14fe2m653f899feb45cbdd@mail .gmail.com>, Foss User
wrote:
>$ ls
>convert.sh Track 1.wav Track 3.wav Track 5.wav Track 7.wav Track 9.wav
>Track 1.mp3 Track 2.wav Track 4.wav Track 6.wav Track 8.wav
>
>So, you can see there are file names with spaces in them. I have
>written a script like this to handle one file name at a time.
>
>for file in `ls *.wav`
>do
> echo $file
>done
>
>Of course, this doesn't do what I need. The names are split wherever
>there are spaces.

That's because you are using a useless subshell for a useless ls, and failing
to quote your variables. You need:

for f in *.wav; do
echo "$file"
done

ls is not responsible for doing filename expansion ("globbing"); the shell is,
so let the shell do it. Since you aren't using a subshell, word-splitting is
not done on its output.

The quotes are required to prevent the shell from performing word-splitting on
the contents of the variable; i.e. to prevent the filename "Track 2.wav" to
be sent to the echo command/built-in as two arguments: "Track" and "2.wav".
You wouldn't notice a difference in this case unless your filenames contained
tabs, newlines, or consecutive whitespace characters.
--
Boyd Stephen Smith Jr. ,= ,-_-. =.
bss@iguanasuicide.net ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-'
http://iguanasuicide.net/ \_/
 
Old 01-06-2010, 01:57 PM
Jon Dowland
 
Default Handle each file at a time in loop?

On Tue, Jan 05, 2010 at 02:00:31AM +0530, Foss User wrote:
> for file in `ls *.wav`
> do
> echo $file
> done
>
> Of course, this doesn't do what I need. The names are
> split wherever there are spaces.
>
> $ sh convert.sh
snip
> What is the right way to do this?

Aside from correctly quoting your variables (as others have
pointed out), you could also use a combination of find(1)
and xargs(1). This is a generally robust approach for files
which might have any number of awkward characters in the
names: spaces, unprintable characters, files beginning with
dashes (which programs might mistake/confuse for arguments),
etc.

Especially if you are doing some kind of encoding (as
convert.sh + .wav files suggests) and have a multi-core
system. In this situation, the '-P' argument to GNU xargs is
a nice feature for parallel execution. E.g.

$ find . -type f -name '*.wav' -print0 | xargs -r0 -n 1 -P 4 lame -S

Here find generates a list of files in the current directory
ending in '.wav', prints out a string with the filenames
embedded in it, separated by the NULL byte (so guaranteed
not to be part of a filename itself); xargs then takes this
string and splits it up into filenames, then, assuming there
is at least one argument, runs 'lame -S <file>' for each
file, four invocations at a time[1].

For renaming (to remove .wav from inside foo.wav.mp3, or to
remove the space characters to make files easier to handle),
you might like rename(1) from inside the perl package:

$ rename 's/ /_/g' *wav
$ rename 's/.wav//' *mp3

[1] the exact number you want to use is a matter of
experimentation; number of cores - 1 might be good if
you want to guarantee CPU time to other tasks e.g.
interactive usage; I tend to use number of (cores * 2) -
1 i.e. 7 for a quad-core/hyper-threaded machine


--
Jon Dowland
 

Thread Tools




All times are GMT. The time now is 08:33 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright ©2007 - 2008, www.linux-archive.org