LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 07-15-2009, 03:15 PM   #16
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,551
Blog Entries: 28

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176

Quote:
Originally Posted by Qu3ry View Post
1.new year.mp3
2.linux.mp3
3.hello.mp3

etc...
Sorry, I'm still not clear exactly what you want to do here. You want to rename which *.mp3 files? The "1-01 track.mp3" etc ones as "new year 01 track.mp3" etc?
 
Old 07-15-2009, 03:53 PM   #17
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by catkin View Post
Sorry, I'm still not clear exactly what you want to do here. You want to rename which *.mp3 files? The "1-01 track.mp3" etc ones as "new year 01 track.mp3" etc?
1-01 track.mp3 is one of the split files of 1.new year.mp3.

first to merge, then to rename them.
 
Old 07-15-2009, 04:25 PM   #18
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,551
Blog Entries: 28

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176
Quote:
Originally Posted by Qu3ry View Post
1-01 track.mp3 is one of the split files of 1.new year.mp3.

first to merge, then to rename them.
How do you merge them?
 
Old 07-16-2009, 04:02 PM   #19
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
cat 01-*.mp3 > 01.mp3
cat 02-*.mp3 > 02.mp3

etc..

Writing a for loop to automate the task. The problem is that you have to know number of tracks to be merged in each directory.



Code:
i = 01
j = 32 # number of tracks to be merged

for i <= j ; do 

   cat "$i"-*.mp3 > "$i".mp3; 
   i = $(i + 1) 

done
 
Old 07-16-2009, 08:50 PM   #20
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 2,494

Rep: Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850
What language are those for loops in? I'm pretty that is not valid bash.

This should work, assuming the song number is always separated by a "-" and is the first thing in the file name. Also it might screw up if there are other files in the directory.
Code:
for song in $(ls *-*.mp3 | cut -d- -f1 | sort -u) ; do
   cat "$song"-*.mp3 > "$song".mp3
done
 
Old 07-17-2009, 01:55 PM   #21
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
ntubski, your script should work. However, I found a new pattern in other directories.. Some songs aren't grouped together by their number prefixes. More precisely they are grouped by their names.. for instance..

01-1.song.mp3
01-2.song.mp3
01-3.pop.mp3
01-4.pop.mp3

There are two songs in those 4 files. How to change the script accordingly?

Last edited by Qu3ry; 07-17-2009 at 01:58 PM.
 
Old 07-17-2009, 03:23 PM   #22
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,551
Blog Entries: 28

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176
Hello Qu3ry
Quote:
Originally Posted by Qu3ry View Post
cat 01-*.mp3 > 01.mp3
Code:
i = 01
j = 32 # number of tracks to be merged

for i <= j ; do 

   cat "$i"-*.mp3 > "$i".mp3; 
   i = $(i + 1) 

done
Bash requires no spaces either side of the = command in an assignment. Thus i = 01 does not assign 01 to i. Instead it tries to run the command i with operands = and 01.

Bash interprets integer constants beginning with 0 as octal. Doesn't make any difference for 01 to 07 but 09 would be invalid.

The syntax of the "for" statement is either
Code:
for name [in words ...]
or
Code:
for (( expr1 ; expr2 ; expr3 ))
It looks as if you wanted
Code:
while test-commands
The <= comparison operator is for strings unless you are doing shell arithmetic in a let <arithmetic expression>, ((<arithmetic expression>)) or $((<arithmetic expression>)). The bash test numeric comparison operator is -le.

In cat "$i"-*.mp3 > "$i".mp3; the ";" is OK but not necessary because the line end serves the same purpose.

i = $(i + 1) will not do what you want, first because of the spaces either side of the "=" and second because $(i + 1) will try to run command i with operands + and 1. i=((i + 1)) would do what you want because bash evaluates expressions within (( )) as arithmetic and substitutes their value. Assuming $i is 5 then i=((i + 1)) becomes i=6

This works:
Code:
for (( i=1; i<=32; i++ ))
do
    cat "$i"-*.mp3 > "$i".mp3
done
BTW, I'm amazed and educated to learn that you can cat *.mp3 files together and play the result. Please confirm you have tested this.

Best

Charles
 
Old 07-17-2009, 03:47 PM   #23
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 2,494

Rep: Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850
Quote:
Originally Posted by Qu3ry View Post
01-1.song.mp3
01-2.song.mp3
01-3.pop.mp3
01-4.pop.mp3

There are two songs in those 4 files. How to change the script accordingly?
changes in red.

Code:
for song in $(ls *-*.*.mp3 | cut -d. -f2 | sort -u) ; do
   cat *."$song".mp3 > "$song".mp3
done
Quote:
Originally Posted by catkin
BTW, I'm amazed and educated to learn that you can cat *.mp3 files together and play the result.
You know, now that you mention it, it does seem surprising.

Last edited by ntubski; 07-17-2009 at 03:49 PM. Reason: more precise change indication
 
Old 07-17-2009, 04:15 PM   #24
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
I have been using the cat command to merge avi and mp3 files for awhile with no problem.

For further reference: an article on looping filenames with spaces:

http://www.cyberciti.biz/tips/handli...s-in-bash.html

Last edited by Qu3ry; 07-17-2009 at 04:25 PM.
 
Old 07-17-2009, 04:51 PM   #25
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,551
Blog Entries: 28

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176
Hello Qu3ry
Quote:
Originally Posted by Qu3ry View Post
I have been using the cat command to merge avi and mp3 files for awhile.

For further reference: an article on looping filenames with spaces:

http://www.cyberciti.biz/tips/handli...s-in-bash.html
Thanks for the info.

Slightly scary page on the link though ...

"By default $IFS is set to the space character" is not correct. By default it is set to space, tab and newline.

There's no need to adjust IFS for this code to work when files in the current directory contain spaces (and tabs and newlines!)
Code:
for f in *
do
  echo "$f"
done
It works just fine with the default IFS!

I'm surprised that IFS=$SAVEIFS works. What if there are current IFS characters in $SAVEIFS? Wouldn't the shell evaluate $SAVEIFS into more than one word? IFS="$SAVEIFS" is safer. Mmm ...

In IFS=$(echo -en "\n\b"), why put the backspace character in IFS? Mmm ...

while IFS=: read userName passWord userID groupID geCos homeDir userShell is perfectly correct but neither transparent nor efficient; its only merit is to save a line. Functionally this is identical
Code:
IFS=:
while read userName passWord userID groupID geCos homeDir userShell
Best

Charles
 
Old 07-18-2009, 07:54 AM   #26
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by ntubski View Post
changes in red.

Code:
for song in $(ls *-*.*.mp3 | cut -d. -f2 | sort -u) ; do
   cat *."$song".mp3 > "$song".mp3
done

You know, now that you mention it, it does seem surprising.
ntubski, the new script didn't work. There is no mp3 matches the pattern to begin with. I have changed the code to (ls *-*.mp3) to match the pattern and ran the code with the echo command instead of the cat command. It didn't work neither. Here is the result:

*.mp3.mp3 to mp3.mp3

where "to" is the replacement of ">"

Last edited by Qu3ry; 07-18-2009 at 10:15 AM.
 
Old 07-18-2009, 08:24 AM   #27
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
catkin, I find using files=($(ls *.mp3)) as an array assignment not able to deal with filenames with spaces. Changing it to files=( *.mp3 ) can solve the problem.



Code:
files=( *.mp3 )
i=0
cat test.txt | while read j
do
    mv "${files[ $i ]}" "$j".mp3 
    let i++
done
BTW, for those of you who are lucky to have id3 tag attached to their mp3es, there is a program to rename mp3es according to their id3 tag and vice versa.

http://pwp.netcabo.pt/paol/tagtool/

Last edited by Qu3ry; 07-18-2009 at 08:34 AM.
 
Old 07-18-2009, 09:22 AM   #28
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,551
Blog Entries: 28

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176
Hello Qu3ry
Quote:
Originally Posted by Qu3ry View Post
catkin, I find using files=($(ls *.mp3)) as an array assignment not able to deal with filenames with spaces. Changing it to files=( *.mp3 ) can solve the problem.
Thanks for the correction and sorry for the mistake.

Best

Charles
 
Old 07-18-2009, 12:15 PM   #29
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 2,494

Rep: Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850
Quote:
Originally Posted by catkin View Post
while IFS=: read userName passWord userID groupID geCos homeDir userShell is perfectly correct but neither transparent nor efficient; its only merit is to save a line. Functionally this is identical
Code:
IFS=:
while read userName passWord userID groupID geCos homeDir userShell
I agree with all your other criticisms, but using while IFS=: read userName passWord userID groupID geCos homeDir userShell does have the advantage that IFS gets reset back to previous value after read command finishes.

Quote:
Originally Posted by Qu3ry
ntubski, the new script didn't work. There is no mp3 matches the pattern to begin with. I have changed the code to (ls *-*.mp3) to match the pattern and ran the code with the echo command instead of the cat command. It didn't work neither. Here is the result:

*.mp3.mp3 to mp3.mp3

where "to" is the replacement of ">"
It works for me:
Code:
~/tmp/songs$ ls
01-1.song.mp3  01-2.song.mp3  01-3.pop.mp3  01-4.pop.mp3
~/tmp/songs$ for song in $(ls *-*.*.mp3 | cut -d. -f2 | sort -u) ; do
> echo *."$song".mp3 to "$song".mp3
> done
01-3.pop.mp3 01-4.pop.mp3 to pop.mp3
01-1.song.mp3 01-2.song.mp3 to song.mp3
 
Old 07-18-2009, 12:22 PM   #30
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,551
Blog Entries: 28

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176
Quote:
Originally Posted by ntubski View Post
I agree with all your other criticisms, but using while IFS=: read userName passWord userID groupID geCos homeDir userShell does have the advantage that IFS gets reset back to previous value after read command finishes.
Thanks Interesting! How does that work? AIUI, it would only happen if "while" set up a subshell -- but, if that's the case, how are any variables set in the loop available in the parent shell?
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Find/grep command to find matching files, print filename, then print matching content stefanlasiewski Programming 8 12-18-2013 05:36 PM
Trouble with making a bash script to read in different files and rename output files. rystke Linux - Software 1 05-07-2009 08:00 AM
list files NOT matching a pattern smart_sagittari Linux - Newbie 9 05-20-2005 05:32 AM
awk cli to rename a list of files... pld Linux - General 4 02-15-2005 10:57 PM
Is it possible to rename an Ezmlm maling list? tomdkat Linux - Software 0 02-02-2005 04:00 PM


All times are GMT -5. The time now is 04:34 PM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration