Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
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.
I have downloaded a few albums and when I play them back through mplayer, they play songs out of sequence. For some albums the official song sequence is important and I don't like hearing them played back out of order. Is there anything that can be done to correct this? I have been using a terminal with the command:
mplayer ~/Music/folder/album title *.mp3.
Then the album begins with track 10! Why would this be? I welcome any advice on how to get the tracks to play in order. I should add that the numbered play list is perfectly in order, but the songs won't play that way. I will appreciate any input on this--thanks in advance.
Tink, this is not quite what I mean...I don't think. The songs are actually listed in correct numerical order--they appear in the folder in the proper numeric sequence. But the song sequence begins with song #10 goes through #14 and then starts 1-9. It's weird. My sense is this is the order in which the songs were downloaded and that's why they play back in that order, regardless of the numbers in front of them. Looking at your chart, I'm wondering: Does it matter whether you have the numbered sequence as "01, 02, 03, etc." as opposed to "1,2,3...etc."? As I said, it doesn't proceed "10, 1, 2, 3...etc." It goes from "10, 11, 12, 13, 14 and then begins with "1, 2, 3...up to 9" and then ends. If I do need to change this numbering sequence so the computer understands in which order to play back the songs, where do I make these changes? Thanks!
That certainly looks like ascii sort order to me. The system doesn't treat the digits as numbers, but only as individual characters; so it starts by sorting the first character in the names (all the ones first, then all the twos, etc), then sorts the second character, etc.
But whether or not the sort order is ascii, whenever you use globbing you're going to get the files in the order the system thinks they should be in, and it's probably not going to be numerical order. Try using "printf '%s\n' *.mp3" to see exactly what file order the pattern produces.
In any case, padding the numbers with zeros will likely give you the playback order you want. Another option may be to pipe the list through sort -n, but getting the output to work correctly might be tricky if there are spaces in the filenames.
I wrote a script a while back that will pad numbers in filenames. Give it a try.
Code:
#!/bin/bash
# Pads numbers in file names if found.
# See help message for more.
# Set the environment
shopt -s extglob
IFS=""
BCYAN="${BCYAN:-\e[1;36m}" #Define some color codes, for prettified output.
#BGREEN="${BGREEN:-\e[1;32m}" #Use environment defaults if they exist.
#BRED="${BRED:-\e[1;31m}"
#BBLUE="${BBLUE:-\e[1;34m}"
#BMAGENTA="${BMAGENTA:-\e[1;35m}"
RESET="${RESET:-\e[0m}"
#set default padding level
pad=2
# Set up the help dialog
help(){
local -a help
help+=( '' )
help+=( '\tA quick script to zero-pad files that contain numbers.' )
help+=( '\tIt will only pad the first number string it finds in the name, and ignores files without numbers.' )
help+=( '' )
help+=( "\tUsage: \t${BCYAN}${0##*/} [-n <num>] <files>${RESET}" )
help+=( "\t\t${BCYAN}${0##*/} -h${RESET}" )
help+=( '' )
help+=( '\tUse -n to specify the number of digits to pad, from 1-9. Defaults to '"$pad"' if not used.' )
help+=( '\tIf no files are given, it processes the current directory.' )
help+=( '' )
help+=( '\t-h prints this help message' )
help+=( '' )
local IFS=$'\n'
echo -e "${help[*]}"
}
# Process input options
# If "-h" print help & exit.
# If "-n" test for valid inputs and set "pad" variable
# Ignore anything else
while getopts ":hn:" opt; do
case "$opt" in
h) help >&2
exit "2"
;;
n) if [[ "$OPTARG" =~ [^[:digit:]] ]] || (( "10#$OPTARG" < 1 )) || (( "10#$OPTARG" > 9 )); then
echo
echo -e "${BCYAN}invalid option: [$OPTARG].${RESET}" >&2
echo -e "${BCYAN}-n must be an integer from 1 to 9${RESET}" >&2
echo -e "${BCYAN}Falling back to the default of $pad${RESET}"
echo
else
pad="$(( 10#$OPTARG ))"
fi
;;
\?) echo -e "${BCYAN}Invalid option: [-$OPTARG]. Ignoring.${RESET}" >&2
;;
esac
done
shift $(( OPTIND - 1 )) ; OPTIND=1
# Now test for files.
# If nothing given, set input parameters to files in current directory.
if [[ -z "$*" ]]; then
set -- ./*
fi
# Process files in input parameters
re='([^[0-9]*)([0-9]+)(.*)'
for file ; do
# Ignore files without digits
[[ "$file" != *[0-9]* ]] && continue
# Split filename into prefix-digits-suffix
[[ "$file" =~ $re ]]
# Pad digits to desired width
printf -v numpad "%0*d" "$pad" "${BASH_REMATCH[2]##*(0)}"
# Add old and new filenames to arrays for final processing
oldfile+=( "$file" )
newfile+=( "${BASH_REMATCH[1]}${numpad}${BASH_REMATCH[3]}" )
done
# If there are any files to rename, ask to confirm the operation.
# And rename if confirmed.
if [[ -n "${oldfile[*]}" ]]; then
echo
echo -e "${BCYAN}Rename the following files?${RESET}"
echo
for i in "${!oldfile[@]}" ; do
echo -e "${oldfile[i]/#$PWD/.}\t-->\t${newfile[i]/#$PWD/.}"
done
echo
read -p "(y/n): "
echo
case "${REPLY,,}" in
y*) for i in "${!oldfile[@]}" ; do
mv -n "${oldfile[i]}" "${newfile[i]}"
done
echo
;;
*) echo -e "${BCYAN}Aborting.${RESET}"
echo
exit 1
;;
esac
# Otherwise just exit.
else
echo
echo -e "${BCYAN}No files to rename.${RESET}" >&2
echo -e "${BCYAN}Exiting.${RESET}" >&2
echo
exit 1
fi
exit 0
Last edited by David the H.; 04-17-2012 at 09:13 AM.
David, your explanation was excellent and professional...but way too technical for me! I admire your script writing abilities and wish I had a portion of your knowledge. As it turns out, just inserting the "0" before the single digits did the trick! In the future, what's the way to accomplish this changing of numbers sequence in the terminal? I had to go into the music folder on my desktop and then "rename" the 1-9 songs individually. Is there a more expedient way you can accomplish this within the terminal, without having to rewrite the name of the whole song and the number? Thanks for this. Very helpful! Incidentally, if you have any suggestions for how a Linux novice can become more proficient with scripting, or just knowing how to use basic commands in the terminal, I would welcome your suggestions! Again, thanks Trink and David!
Is there a more expedient way you can accomplish this within the terminal, without having to rewrite the name of the whole song and the number?
Um, yeah. With the script I just posted.
Copy the text into a text file and name it to something like "padnumbers.sh". Make it executable with "chmod -x padnumbers.sh". then just run "/path/to/padnumbers.sh *.mp3". It zero-pads files with numbers to two digits by default, and it will prompt you for confirmation.
As for learning scripting, study and practice, just like anything else. 10 years ago I was a rank beginner too. And now there are better resources available.
I had to go into the music folder on my desktop and then "rename" the 1-9 songs individually. Is there a more expedient way you can accomplish this within the terminal, without having to rewrite the name of the whole song and the number?
You can also use easytag to do the renaming from a GUI if you prefer.
Select the files you want to rename. Scanner-> Process Fields, change to 'Rename File and Directory'. I use 'n%.t%' (tracknumber.tracktitle) myself, that would give you filenames like '01.trackone'. I dont bother with artist, year, etc. in the fielname as that is in the path with my system (so the full path would be something like /Music/S/Severed.Heads/1989.Rotund.For.Success/01.All.Saints.Day.flac)
That will only work if your tags are filled. You can normally get the tag info from CDDB, and if that doesnt work you can fill the tag fileds from the file naming. E.g. if the file names are '1abc' like in Tinksters example, you should be able to get track number and song title.
Thanks one and all for the complete info! Duly appreciated! When inserting a script, does it have to be identified as such or does Linux simply recognize a script as distinct from a command? I wanted to be sure how to include David's script above. Last night a friend sent me another script he said might work.
#!/bin/sh
mplayer `ls ~/$1/*.mp3 |sort -df`
Does this seem it would do the job? I know little about scripts other than I'm impressed with people's ability to write them! Without diverting too much from the topic at hand, both this script and David's above were written for Bash editors. I've heard some people sing the praises of KornShell as an editor. What determines the use for one editor over another?
Thanks one and all for the complete info! Duly appreciated! When inserting a script, does it have to be identified as such or does Linux simply recognize a script as distinct from a command? I wanted to be sure how to include David's script above. Last night a friend sent me another script he said might work.
#!/bin/sh
mplayer `ls ~/$1/*.mp3 |sort -df`
Does this seem it would do the job? I know little about scripts other than I'm impressed with people's ability to write them! Without diverting too much from the topic at hand, both this script and David's above were written for Bash editors. I've heard some people sing the praises of KornShell as an editor. What determines the use for one editor over another?
I doubt it would make a change to the way they're played back; sort -df,
apart for comparing upper & lower-case letters as equal, sorts in the
same was as shell globbing, so 10, 11, 12 would still show before 2.
The shell treats the first word on the command line as the name of the command to execute. If a file matching that name is found in one of your PATH directories (use "echo $PATH" to see), and is executable, then the shell will launch it. If the command is not in your path, then you have to supply it with the full (relative or absolute) pathname (e.g. "./scriptname"), to tell the shell where it is.
As for that new script, you'll notice I already mentioned piping the output through sort, and the problems you'll likely encounter if there are any spaces in the filenames. As written, the shell will be unable to differentiate between whitespace inside the names and the whitespace separating them. You'd have to use a more complex loop and null separators to do it safely. Nor should it be using ls to supply sort with the file list, for pretty much the same reason.
Finally, as Tinkster mentioned, it really needs to be using the -n (numeric sorting) option rather than -d (dictionary sorting).
It is possible to write a safe script, but it's really much better in the long run just to ensure that your files are properly padded.
Last edited by David the H.; 04-19-2012 at 08:25 AM.
Reason: minor rewording
As for your choice of shell, in the end it comes down to personal choice. They all have individual features, syntax, and quirks to differentiate them. ksh and bash seem to have a pretty good mutual feedback thing going, where new features appearing in one eventually make it into the other, although it appears that korn is the one that usually introduces new ideas first. At an off-guess, I'd say about 80% of their shell grammar is the same.
bash is the default on Linux, of course, and therefore the one that most people know the best. Most of the users here have little experience with ksh or other shells, meaning you're less likely to get less helpful advice from us.
If you really want a feature-rich shell, you might check out zsh, which is an attempt to combine the best (in the developer's opinions) features of all the other shells. Or if you want to go the other way, stick with posix-defined syntax only, and use dash (I don't recommend this, BTW), or try the new simplified, non-posix fish.
Whatever you do, though, you probably should not choose any of the c-shell variants.
Thanks for all the above. Really, I'm not savvy enough to distinguish between the merits/demerits of the various shells. I've just heard from some, apparently accurately, that ksh is a few notches ahead of bash and those who know it well (ksh) are in demand. It is perhaps that slight edge over bash that David speaks of. Is learning the language of the shell different from learning the commands of Linux generally? What is the relation of the particular shell to the basic Linux program? I still use Ubuntu so I'm just feeling my way to the command line.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.