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.
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?
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.
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
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..
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.
"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
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:
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.
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.
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
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?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.