LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
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-12-2009, 11:44 AM   #1
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Rep: Reputation: 15
Rename files matching a list


Is there a way, preferably in python or BASH, to rename files from a list? for instance, track1.mp3, track2.mp3 should be renamed to the names stored in a file listing song names.

I have tried to loop a variable through directory listing and renamed them, only to find that filenames with spaces can't be assigned to a variable as a whole.

To solve the problem above, I have tried the read command in BASH, which enables the program reading line by line from a list. However, It was failed to pipe the results from directory listing to the read command.

Any help is appreciated !

Last edited by Qu3ry; 07-12-2009 at 11:46 AM.
 
Old 07-12-2009, 12:22 PM   #2
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Hello Qu3ry

Yes, it's possible. You've probably got some bash quoting issues. If you post your script we can take it from there.

Best

Charles
 
Old 07-12-2009, 02:28 PM   #3
sutrannu
LQ Newbie
 
Registered: Nov 2007
Location: USA, Midwest
Distribution: ubuntu
Posts: 13

Rep: Reputation: 1
Code:
  for x in `seq 1 $(ls *.mp3|wc -l)`; do mv `ls *.mp3|head -$x|tail -1` `cat Track_List.txt|head -$x|tail -1|sed 's/[^0-9a-zA-Z]/_/g'`.mp3; done
Something like this would rename the mp3s in a folder with names from Track_List.txt if the number of mp3s matched the names in the file, they were in the same order, etc.
This is quick & dirty. Backup, and test first.
This will replace all non-alphanumeric characters with "_".
 
Old 07-14-2009, 08:57 AM   #4
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
How to combine these two?

Condition A
Code:
#!/bin/bash

for i in `ls *.mp3`; do echo i is $i; done
Condition B
Code:
#!/bin/bash

cat test.txt | while read j; do echo j is $j; done
The idea is to rename $i to $j. How to combine the first two conditions using the AND logical operator?

ie. If condition A and B is true, then rename i into j for each iteration

Last edited by Qu3ry; 07-14-2009 at 09:03 AM.
 
Old 07-14-2009, 10:19 AM   #5
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Hello Qu3ry

A and B are loops, not "conditions". In programming, a condition is a test -- equality, greater than, less than , existence etc.

How about reading the list of files into an array first and then loop through the lines of test.txt?

Code:
files=($(ls *.mp3))
i=0
cat test.txt | while read j
do
    echo mv "${files[ $i ]}" "$j" 
    $(( i = i + 1 ))
done
The var=(<stuff>) creates var as an array and assigns the (whitespace separated) words of <stuff> to successive elements of the array. By default, whitespace is space, tab and newline . The form given above will work as long as there is no whitespace in the *.mp3 file names.

$(<stuff>) is doing the same as your `<stuff>` but is more robust.

$i is set to 0 before starting the loop because that is the index of the first element of the array.

Putting the $j in double quotes overcomes the problem of file names including spaces; it keeps the whole name together as a single word; without the double quotes, each (whitespace separated) word of $j would become a separate argument to the echo (later mv) command.

$(( <stuff> )) is for doing arithmetic.

The code is proof of concept (and not tested!) rather than smart. It doesn't check for test.txt having the same number of lines as there are *.mp3 files and it would be easier to read if $j was renamed to something meaningful like $track_name.

Best

Charles

Last edited by catkin; 07-14-2009 at 10:28 AM. Reason: Typos and more
 
1 members found this post helpful.
Old 07-15-2009, 11:38 AM   #6
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
Thanks catkin for your help.

Some song names listed in the file ends with a trailing ^M, probably as a result of Windows-copy-and-paste thingy. I ran the script before using the dos2unix command. Songs are bearing weird endings. For instance, songname??.mp3

I have tried to rename them by using the rename command, but in vain.

Code:
#rename ^M.mp3 .mp3 *
Having tried \^M.mp3, "\^M.mp3" or ?.mp3, I found nothing work so far.

Last edited by Qu3ry; 07-15-2009 at 11:44 AM.
 
Old 07-15-2009, 11:51 AM   #7
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
BTW, the following msg was found in the prompt when running your script. ( I have the echo command removed btw)

Quote:
/usr/bin/match.sh: line 8: 1: command not found
/usr/bin/match.sh: line 8: 2: command not found
/usr/bin/match.sh: line 8: 3: command not found
/usr/bin/match.sh: line 8: 4: command not found
/usr/bin/match.sh: line 8: 5: command not found
/usr/bin/match.sh: line 8: 6: command not found
/usr/bin/match.sh: line 8: 7: command not found
/usr/bin/match.sh: line 8: 8: command not found
/usr/bin/match.sh: line 8: 9: command not found
/usr/bin/match.sh: line 8: 10: command not found
/usr/bin/match.sh: line 8: 11: command not found
/usr/bin/match.sh: line 8: 12: command not found
/usr/bin/match.sh: line 8: 13: command not found
/usr/bin/match.sh: line 8: 14: command not found
/usr/bin/match.sh: line 8: 15: command not found
/usr/bin/match.sh: line 8: 16: command not found
/usr/bin/match.sh: line 8: 17: command not found
/usr/bin/match.sh: line 8: 18: command not found
/usr/bin/match.sh: line 8: 19: command not found
/usr/bin/match.sh: line 8: 20: command not found
/usr/bin/match.sh: line 8: 21: command not found
/usr/bin/match.sh: line 8: 22: command not found
/usr/bin/match.sh: line 8: 23: command not found
/usr/bin/match.sh: line 8: 24: command not found

Last edited by Qu3ry; 07-15-2009 at 11:52 AM.
 
Old 07-15-2009, 12:20 PM   #8
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Hello Qu3ry

The Ctrl+M characters can be removed in the script:
Code:
ctlM=$'\r'
files=($(ls *.mp3))
i=0
cat test.txt | while read j
do
    echo mv "${files[ $i ]}" "${j%$ctlM}" 
    $(( i = i + 1 ))
done
The form var=$'<stuff>' allows C escape sequences to be used in defining a string. C escape sequence \r is Ctrl+M.

Any text editor can be used to create the above script. If you are using an editor that allows insertion of Ctrl+M you wouldn't need the $ctlM variable. In vi you can enter it directly by pressing Ctrl+V then Ctrl+M. So you could replace "${j%$ctlM}" with "${j%$^M}".

Best

Charles
 
Old 07-15-2009, 02:18 PM   #9
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
This time is little bit different. I was about to rename a bunch of mp3 files having the following patterns:

1-01 track.mp3
1-02 track.mp3
1-03 track.mp3
1-04 track.mp3
1-05 track.mp3
1-06 track.mp3

2-01 song.mp3
2-02 song.mp3
2-03 song.mp3
2-04 song.mp3

How to merge all split files according to their track numbers? There is no info on how many parts are split for each song. The only info we know is they all have the same number prefixes.

The problem with for loop is that you have to know the largest number prefix in orker to loop. Also, is there a better way to extract their filenames?

Quote:
i=1
for i < 30
do
cat "$i"* > "$i".mp3
i = i + 1
done

Last edited by Qu3ry; 07-15-2009 at 02:47 PM.
 
Old 07-15-2009, 02:30 PM   #10
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
manipulating song lists

Problem with the tr command in BASH

I want to replace all filenames beginning with single digit prefixes into muliti-digits. For instance 1.song.mp3 into 01.song.mp3.

Code:
tr '^[1-9]\.$' '0[1-9]\.' <text.txt
It didn't work for unknown reasons.

Another interesting thing is that when text.txt is streamed through tr with the same filename as output, it didn't replace the old one with the new.

Code:
tr 'a' '1' <test.txt > text.txt
text.txt would be blank. why ? I have to use a new filename other than text.txt as output.

Last edited by Qu3ry; 07-15-2009 at 02:55 PM.
 
Old 07-15-2009, 02:39 PM   #11
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by Qu3ry View Post
BTW, the following msg was found in the prompt when running your script. ( I have the echo command removed btw)
Did you solve that issue? If not, try replacing
Code:
$(( i = i + 1 ))
with
Code:
let i=i+1
 
Old 07-15-2009, 02:41 PM   #12
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by Qu3ry View Post
This time is little bit different. I was about to rename a bunch of mp3 files having the following patterns:

1-01 track.mp3
1-02 track.mp3
1-03 track.mp3
1-04 track.mp3
1-05 track.mp3
1-06 track.mp3

2-01 song.mp3
2-02 song.mp3
2-03 song.mp3
2-04 song.mp3

How to merge all split files according to their track numbers? There is no info on how many parts are split for each song. The only info we know is they all have the same number prefixes.
What does the corresponding test.txt file look like?
 
Old 07-15-2009, 02:53 PM   #13
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by catkin View Post
What does the corresponding test.txt file look like?
1.new year.mp3
2.linux.mp3
3.hello.mp3

etc...
 
Old 07-15-2009, 03:10 PM   #14
Qu3ry
LQ Newbie
 
Registered: Jul 2009
Distribution: ubuntu, fedora, OpenSolaris
Posts: 21

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by catkin View Post
Did you solve that issue? If not, try replacing
Code:
$(( i = i + 1 ))
with
Code:
let i=i+1
after replacing it with "let i=i+1"

/usr/bin/match.sh: line 9: let: =: syntax error: operand expected (error token is "=")
 
Old 07-15-2009, 03:11 PM   #15
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by Qu3ry View Post
Problem with the tr command in BASH

I want to replace all filenames beginning with single digit prefixes into muliti-digits. For instance 1.song.mp3 into 01.song.mp3.

Code:
tr '^[1-9]\.$' '0[1-9]\.' <text.txt
I don't understand what the tr operands (SET1 and SET2 on the man page) are and anyway, what's going to happen when you get to 10.song.mp3? Might be easier to parse out the number (by ${name%%.*}) and format it as you want using printf.

Quote:
Originally Posted by Qu3ry View Post
Code:
tr 'a' '1' <test.txt > text.txt
text.txt would be blank. why ? I have to use a new filename other than text.txt as output.
The shell empties the file after the > before running the command.
 
  


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 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 9 06-30-2016 05:30 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

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:08 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