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 ! |
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 |
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 This is quick & dirty. Backup, and test first. This will replace all non-alphanumeric characters with "_". |
How to combine these two?
Condition A
Code:
#!/bin/bash Code:
#!/bin/bash ie. If condition A and B is true, then rename i into j for each iteration |
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)) $(<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 |
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 * |
BTW, the following msg was found in the prompt when running your script. ( I have the echo command removed btw)
Quote:
|
Hello Qu3ry :)
The Ctrl+M characters can be removed in the script: Code:
ctlM=$'\r' 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 |
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:
|
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 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 |
Quote:
Code:
$(( i = i + 1 )) Code:
let i=i+1 |
Quote:
|
Quote:
2.linux.mp3 3.hello.mp3 etc... |
Quote:
/usr/bin/match.sh: line 9: let: =: syntax error: operand expected (error token is "=") |
Quote:
Quote:
|
Quote:
|
Quote:
first to merge, then to rename them. |
Quote:
|
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:
|
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 |
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? |
Hello Qu3ry :)
Quote:
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 ...] Code:
for (( expr1 ; expr2 ; expr3 )) Code:
while test-commands 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++ )) Best Charles |
Quote:
Code:
for song in $(ls *-*.*.mp3 | cut -d. -f2 | sort -u) ; do Quote:
|
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 |
Hello Qu3ry :)
Quote:
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 * 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 ... :confused: In IFS=$(echo -en "\n\b"), why put the backspace character in IFS? Mmm ... :confused: 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=: Charles |
Quote:
*.mp3.mp3 to mp3.mp3 where "to" is the replacement of ">" |
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:
http://pwp.netcabo.pt/paol/tagtool/ |
Hello Qu3ry :)
Quote:
Best Charles |
Quote:
Quote:
Code:
~/tmp/songs$ ls |
Quote:
|
There is no subshell, assignments before a command are only in effect for that command.
Simple-Command-Expansion: Quote:
|
Quote:
Just for fun (and the upcoming obfuscated bash competition): Code:
a=X b=Y c=Z env |
Sorry ntubski, I have given you the wrong info. There should be no dot between the numerals and the song names.
01-01 song with spaces in filename.mp3 01-02 song with spaces in filename.mp3 etc... I have changed the script to (ls *-*\ *.mp3),but it didn't work. Can you explain how does your "cut -d. -f2" work? |
BTW, Files I want to rename are scattered across different folders. for instance, they are all in different subfolders. How can I move them one directory up in order to rename them in batch?
Quote:
EDIT: I have figured it out: in working directory, type Quote:
|
Quote:
Here's a version that assumes the song name is the part that comes after the numbers and dashes. I had to rearrange the loop a bit to handle whitespace. Code:
~/tmp/songs$ while read -d$'\n' song ; do |
All times are GMT -5. The time now is 12:57 AM. |