ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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 "_".
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
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.
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
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}".
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
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?
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
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.