Unix Shell - Set a variable to every line of a find -exec loop

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > December 2007 > Set a variable to every line of a find -exec loop





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Set a variable to every line of a find -exec loop
Gnarlodious

2007-12-07, 7:23 pm

I want to set the MP3 tag on thousands of song files with a simple
script. This lists the contents of all tags:

find . -name .mp3 -exec id3tool {} \;

Now I want to set a variable to every filepath found, parse the
variable string and use the components to set the tag. Is this possible
in such a simple loop? How would I set a variable and reuse it inside
the loop?

Thanks. This is OSX 10.5.

-- Gnarlie
http://Gnarlodious.com/


--
Posted via a free Usenet account from http://www.teranews.com

Barry Margolin

2007-12-08, 7:42 pm

In article <4759b5c9$0$26011$88260bb3@free.teranews.com>,
Gnarlodious <lists.gnarlodious@gmail.com> wrote:

> I want to set the MP3 tag on thousands of song files with a simple
> script. This lists the contents of all tags:
>
> find . -name .mp3 -exec id3tool {} \;
>
> Now I want to set a variable to every filepath found, parse the
> variable string and use the components to set the tag. Is this possible
> in such a simple loop? How would I set a variable and reuse it inside
> the loop?
>
> Thanks. This is OSX 10.5.
>
> -- Gnarlie
> http://Gnarlodious.com/


find . -name .mp3 | while read filename;
do
# Use "$filename" in here
done

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Gnarlodious

2007-12-08, 7:42 pm

On 2007-12-08 10:13:22 -0700, Barry Margolin said:
[vbcol=seagreen]
> find . -name .mp3 | while read filename;
> do
> # Use "$filename" in here
> done


OK, I had tried this. What I am saying is:

find . -name *.mp3 | while read filename ; do id3tool $filename ; done ;

however I get hundreds of lines like this:

id3tool: Can't open file "./Music" for read.

It might be the equivalent to saying:

find . -name *.mp3 | while read filename ; do ls $filename ; done

So what I need is the entire filepath, not just components broken at spaces.

Thanks.

-- Gnarlie


--
Posted via a free Usenet account from http://www.teranews.com

Stephane Chazelas

2007-12-08, 7:42 pm

On Sat, 8 Dec 2007 13:33:34 -0700, Gnarlodious wrote:
> On 2007-12-08 10:13:22 -0700, Barry Margolin said:
>
>
> OK, I had tried this. What I am saying is:
>
> find . -name *.mp3 | while read filename ; do id3tool $filename ; done ;


find . -name '*.mp3 -print |
while IFS read -r filename; do
id3tool "$filename"
done

Or you could use zsh and do:

for f (./**/*.mp3) id3tool $f

(note that zsh wouldn't list hidden files and descend into
hidden dirs by default, contrary to find).


--
Stephane
Gnarlodious

2007-12-08, 7:42 pm

On 2007-12-08 13:59:32 -0700, Stephane Chazelas said:
>
> find . -name *.mp3 -print |
> while IFS read -r filename; do
> id3tool "$filename"
> done


Hmmm... that doesn't work in OSX:

-bash: IFS: command not found

But this does, wrapping the variable in double quotes:

find . -name *.mp3 | while read filename ; do id3tool "$filename" ; done

Note that single quotes, which I had tried, do not work:

Can't open file "$filename" for read.

Thanks, question is answered.

-- Gnarlie


--
Posted via a free Usenet account from http://www.teranews.com

Gnarlodious

2007-12-08, 7:42 pm

My next question is, how do I force the awk script in parentheses to
execute first? As it is, the script writes "awk" in the field where
$value should be written. Enclosing in backticks also does not work.

find . -name *.mp3 | while read path ; do value=(awk 'BEGIN
{FS="/"};{print $2}') ; id3tool -r $value "$path" ; done

Alternatively, replacing $value with awk 'BEGIN {FS="/"};{print $2}')
would work, but I do not know how to do this.

Thanks.

-- Gnarlie
http://Gnarlodious.com/


--
Posted via a free Usenet account from http://www.teranews.com

Bill Marcum

2007-12-08, 7:42 pm

On 2007-12-09, Gnarlodious <lists.gnarlodious@gmail.com> wrote:
>
>
> My next question is, how do I force the awk script in parentheses to
> execute first? As it is, the script writes "awk" in the field where
> $value should be written. Enclosing in backticks also does not work.
>
> find . -name *.mp3 | while read path ; do value=(awk 'BEGIN
> {FS="/"};{print $2}') ; id3tool -r $value "$path" ; done
>

value=$(echo "$path" | awk 'BEGIN{FS="/"}{print $2}')

> Alternatively, replacing $value with awk 'BEGIN {FS="/"};{print $2}')
> would work, but I do not know how to do this.
>
> Thanks.
>
> -- Gnarlie
> http://Gnarlodious.com/
>
>

Gnarlodious

2007-12-09, 1:35 am

On 2007-12-08 18:02:40 -0700, Bill Marcum said:


> value=$(echo "$path" | awk 'BEGIN{FS="/"}{print $2}')


Excellent, I learned a new technique. The entire script, executed on
one line in terminal, looks like this:

find . -name *.mp3 | while read path ; do title=$(echo $path | sed
's|.*/\(.*\)\.mp3$|\1|') ; id3tool -t "$title" "$path" ; artist=$(echo
$path | awk 'BEGIN{FS="/"}{print $2}') ; id3tool -r "$artist" "$path" ;
done

See any way to make this shorter?

This script sets MP3 version 3 tags for song title and artist as taken
from the filepath components. It is meant for files arranged in iTunes'
default filesystem format. The script is to be run in terminal with the
working directory at the artist folder, which means the song files are
2 folders below.

-- Gnarlie
http://Gnarlodious.com/Computer/iTunes/MP3Tags



--
Posted via a free Usenet account from http://www.teranews.com

Janis Papanagnou

2007-12-09, 1:35 am

Gnarlodious wrote:
> On 2007-12-08 18:02:40 -0700, Bill Marcum said:
>
>
>
>
> Excellent, I learned a new technique. The entire script, executed on one
> line in terminal, looks like this:
>
> find . -name *.mp3 | while read path ; do title=$(echo $path | sed
> 's|.*/\(.*\)\.mp3$|\1|') ; id3tool -t "$title" "$path" ; artist=$(echo
> $path | awk 'BEGIN{FS="/"}{print $2}') ; id3tool -r "$artist" "$path" ;
> done
>
> See any way to make this shorter?


Why did you put all in a single line? That makes it just incomprehensible.

I suggest some changes (code reformatted and untested; original code left
in as comment)...


# find . -name *.mp3 |
find . -name "*.mp3" -type f |

# while read path
while IFS= read -r path
do
# title=$(echo $path | sed 's|.*/\(.*\)\.mp3$|\1|')
title=${path##*/}
title=${title%.mp3}

id3tool -t "$title" "$path"

# artist=$(echo $path | awk 'BEGIN{FS="/"}{print $2}')
artist=${path#*/}
artist=${artist%%/*}

id3tool -r "$artist" "$path"
done


The changes are; instead of awk, sed, subshells, just use shell builtins.
And some tweaks to make operation more secure in case that *.mp3 files are
in the current directory, or directories carry and .mp3 extension, or the
filenames contain some specific characters.

WRT "shorter" code that you requested; you save a few characters by using
the shell builtins.

Janis

>
> This script sets MP3 version 3 tags for song title and artist as taken
> from the filepath components. It is meant for files arranged in iTunes'
> default filesystem format. The script is to be run in terminal with the
> working directory at the artist folder, which means the song files are 2
> folders below.
>
> -- Gnarlie
> http://Gnarlodious.com/Computer/iTunes/MP3Tags
>
>
>

Barry Margolin

2007-12-09, 7:21 pm

In article <475af3d6$0$26089$88260bb3@free.teranews.com>,
Gnarlodious <lists.gnarlodious@gmail.com> wrote:

> On 2007-12-08 10:13:22 -0700, Barry Margolin said:
>
>
> OK, I had tried this. What I am saying is:
>
> find . -name *.mp3 | while read filename ; do id3tool $filename ; done ;
>
> however I get hundreds of lines like this:
>
> id3tool: Can't open file "./Music" for read.
>
> It might be the equivalent to saying:
>
> find . -name *.mp3 | while read filename ; do ls $filename ; done
>
> So what I need is the entire filepath, not just components broken at spaces.


Use "$filename", not just $filename.

As I said in my example.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2009 webservertalk.com