LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 12-20-2002, 02:27 PM   #1
mathfeel
Member
 
Registered: Feb 2002
Distribution: Gentoo
Posts: 95

Rep: Reputation: 15
simple shell script question


first of all, some background...I am really new to writing BASH scrips...but I find them wonderful...I am trying to write some BASH scrip, but got some problem and no good reference on the web

I have a folder of mp3s, sorter in this way:
/home/user/mp3/artist/albumname/01.mp3
/home/user/mp3/artist/albumname/02.mp3
/home/user/mp3/artist/albumname/03.mp3
...

okay?
but now I want to go through the whole /home/usr/mp3 directory and rename each file like artist_albumname_track#.mp3...

I am wondering couple of things...
1) say I do an ls, it lists the files out...how do I get that into a for loop for that I get to rename them?

3) how does ls distinguish a file from a directory????

3) say I want a variable dirname to have the result of running an ls command (or command in general), how do I do that??
ls > cur writes the result to a FILE, but I want a variable (list) to have the value...

4) for dirname in *
do
cd dirname
done

doesn't work since * would gives directories but as well as files...

thanks
 
Old 12-20-2002, 02:29 PM   #2
mathfeel
Member
 
Registered: Feb 2002
Distribution: Gentoo
Posts: 95

Original Poster
Rep: Reputation: 15
5) say I am in the loop
for name in *;

how do I check if name is a file or directory???
 
Old 12-20-2002, 06:34 PM   #3
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,417

Rep: Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985
i wouldn't use ls for this, i'd use a find statement.

find /home/you/mp3 -iname *.mp3

and then you'll instalty get a very simple list of all mp3's. ls isn't the best for this really.

to test if something is a directory you'd use a test statement like

if [ $filename -d ]
then...

i think that's the right syntax, check the test manpage for confirmation.

watch out for spaces as well if you do soemthing like

for i in `ls /home`

then each time you have a newline OR space it will iterate with that as teh main variable. i saw something on here a while back for how to use entire spaces, have a search around.

persaonlyl i'd say use perl to do this, it's very very similar and no more involved, it'd just make it a lot simpler, as you can pull out the parts of the directory structure so much easier.
 
Old 12-20-2002, 06:42 PM   #4
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Ok, I'll try to write down an example to show you Perl ain't needed for this :-]

We assert all mp3's are under the root /home/user/mp3, and all names of mp3's are to be taken from the subdir's artist/albumname 01.mp3 to produce your "artist_albumname_track#.mp3".

What we need is a command that will find us all files that end on ".mp3". Written out it will look like:
root=/home/user/mp3; find ${root} -type f -name "*.mp3"
Execute this and you'll see the list. The "type -f" isn't really needed int his case, but will come in handy when there are other filetypes dispersed over the search area you don't want to pick up (sockets, for instance).

Now we want to use these names to rename the file. What we do is assign each result of the find query to a variable:
root=/home/user/mp3; find ${root} -type f -name "*.mp3" | while read raw; do
echo ${raw}; done
Execute this and you'll see the list. Not from using "find", but by echoing the contents of the variable.

Each variable looks like "/home/user/mp3/artist/albumname/01.mp3", so we can't use it to rename it to something else. What we need is to split the variable into chewable bits. I like to use arrays' for that:
root=/home/user/mp3; find ${root} -type f -name "*.mp3" | tr "/" " " | while read raw; do m=( ${raw} ); echo ${m[@]}; done
Execute this and you'll see the list. Not from using "find", but by echoing the contents of the array.

Arrays count from zero, and we need parts 3,4 and 5 to rename them mp3's:
root=/home/user/mp3; find ${root} -type f -name "*.mp3" | tr "/" " " | while read raw;
do m=( ${raw} )
echo mv ${raw} ${root}/${raw[3]}_${raw[4]}_${raw[5]}; done

That should do it. If you're convinced this works for you, just remove the last "echo" to commence renaming.

More? Look up the ABS or Bash Advanced Scripting Guide at tldp.org.

HTH.
 
Old 12-20-2002, 06:50 PM   #5
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,417

Rep: Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985
dammit i really wish people would stop running rings around me... pah!
 
Old 12-20-2002, 06:53 PM   #6
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
LOL, no, I just checked before I posted and saw you had ure answer ready first, so I added that 1st line :-]
Blame it on the brewskies
 
Old 12-20-2002, 07:18 PM   #7
nxny
Member
 
Registered: May 2002
Location: AK - The last frontier.
Distribution: Red Hat 8.0, Slackware 8.1, Knoppix 3.7, Lunar 1.3, Sorcerer
Posts: 771

Rep: Reputation: 30
#!/bin/bash

# rename and copy mp3 files

sep=_

# make the destination directory
mkdir -p mymp3

for i in $(find . -type f -name '*.mp3' -print); do
if [ -r $i ]; then
artist=$(echo $i | awk -F/ '{ printf("%s",$(NF-2)) }')
album=$(echo $i | awk -F/ '{ printf("%s",$(NF-1)) }')
track=$(echo $i | awk -F/ '{ printf("%s",$NF) }')

cp $i ./mymp3/$artist$sep$album$sep$track
fi
done

exit 0

The script above will make a new directory mymp3 and copy all the files in there. I changed the 'mv' to a 'cp' because of 2 things.

1) I havent tested it, hehe.
2) I'm not sure if you want a flat directory with all mp3s in there.

You can make a li'l tweak and make every mp3 land on the directory it already is.

start off with 'man test' as acid suggested.. if you're not faint hearted, i'd suggest 'man bash'. Also there is ABS
http://www.tldp.org/LDP/abs/html/index.html
 
Old 12-20-2002, 07:20 PM   #8
nxny
Member
 
Registered: May 2002
Location: AK - The last frontier.
Distribution: Red Hat 8.0, Slackware 8.1, Knoppix 3.7, Lunar 1.3, Sorcerer
Posts: 771

Rep: Reputation: 30
I've told myself a million times to refresh the goddamn thread before I write that up and hit submit. You guys are fast!
 
Old 12-20-2002, 09:30 PM   #9
stickman
Senior Member
 
Registered: Sep 2002
Location: Nashville, TN
Posts: 1,552

Rep: Reputation: 53
I would try something like:
cd /home/usr/mp3
for FILE in `find * -type f -name "*.mp3"`
do
mv $FILE `echo $FILE | sed 's/\//_/g'`
done

This should turn artist/album/track.mp3 into artist_album_track.mp3.

Last edited by stickman; 12-20-2002 at 09:32 PM.
 
Old 12-21-2002, 04:47 AM   #10
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
what happens if you do "mv $FILE" and the name contains spaces?
 
Old 12-21-2002, 04:56 AM   #11
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,417

Rep: Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985Reputation: 1985
well you won't get there with that example, as any spaces will get screwed up in the find statement.
 
Old 03-06-2003, 09:22 AM   #12
Dolamite777
LQ Newbie
 
Registered: Feb 2003
Distribution: Centos
Posts: 17

Rep: Reputation: 0
how do you deal with spaces in script files?

i have a directory /SERVER/example directory/

when the script tries to access the dir it just says

'/SERVER/example': No such file or directory
'directory/': No such file or directory

so what would i need to put in between the dir. name for it to work?
 
Old 03-06-2003, 11:23 AM   #13
nxny
Member
 
Registered: May 2002
Location: AK - The last frontier.
Distribution: Red Hat 8.0, Slackware 8.1, Knoppix 3.7, Lunar 1.3, Sorcerer
Posts: 771

Rep: Reputation: 30
a backslash before the space.

/SERVER/example\ directory/
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Simple shell script mikz Linux - General 1 02-24-2005 07:18 AM
veprory simple but frustrating for a newbie shell script question marigb Linux - Newbie 11 04-28-2004 12:11 PM
simple shell script question. strifel Programming 7 09-13-2003 01:44 PM
simple question on shell script gsbarry Linux - General 2 05-23-2003 04:09 AM
Simple C Shell script is not so simple elconde Programming 2 09-16-2001 11:53 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 01:00 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration