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.
Distribution: Slack, FreeBSD,NetBSD, OpenBSD, Open Solaris, Minix
Posts: 172
Rep:
Bash shell scripting question.
I'm writing a script and wish to do something like this:
for [a-z]*whatever
So basically I'd like it to do whatever when it finds any letter, followed by any character and then various other content. I tried "*","^", and "." to get it to match any character, and none worked. Any help is appreciated.
The question mark matches any single character. Keep in mind, the "[a-z]" will only match lowercase characters. I only mention that because you said "finds any letter" in your description, which is not 100% accurate. For that, you would need "[a-zA-Z]".
Distribution: Slack, FreeBSD,NetBSD, OpenBSD, Open Solaris, Minix
Posts: 172
Original Poster
Rep:
Yes, I'm just pulling a bunch of radio shows from an archive, and when a show is broken in half they add a lowercase letter tag to the end of the filename. If I just do for mp3 in LIST it runs, but wget gives errors, which bothers me. Thanks once again for the help.
Ok, give me some examples of filenames and a little of your script if you don't mind.
EDIT: BTW, when you get an error like that, it usually means there is no match to the wildcard pattern. If the command ls *.mp3 were executed and there were no mp3 files in the directory, the shell would complain that there is no specific "*.mp3" filename (treating the asterisk as a literal character since it didn't match anything when expanded).
Last edited by Dark_Helmet; 09-25-2005 at 01:39 AM.
Oh, ok. Now I understand what's going on. Double-check me:[list=1][*]ask the show's server for a list of files/mp3s[*]filter the returned list for files that match a specific pattern[*]use wget to download those files[/list=1]
If that's the case, the problem is with the for statement. The for statement expects a variable as the first argument: a place to put each element in the list as it works through. In your script it looks like you're trying to put the filtering in the wrong spot. Try this:
Code:
for mp3 in $( echo $LIST | grep "[a-z]\.mp3" )
I changed up the mask a little bit. I'm not sure it will do exactly what you want. It may need to be fine-tuned.
Also, as a side note, the shell handles wildcards differently than regular expressions in Perl or other languages. I don't know if that's what you were shooting for (regular expressions), but wanted to mention it just in case.
Distribution: Slack, FreeBSD,NetBSD, OpenBSD, Open Solaris, Minix
Posts: 172
Original Poster
Rep:
Okay, I hope you don't mind me asking a question or two. "echo $LIST | grep "[a-z]\.mp3" So that pipes the output of echo $LIST to gerp? And also, could you explain that list thing you said:
"Also, as a side note, the shell handles wildcards differently than regular expressions in Perl or other languages. I don't know if that's what you were shooting for (regular expressions), but wanted to mention it just in case."
###Oh and that code works nicely, that you very much.
"echo $LIST | grep "[a-z]\.mp3" So that pipes the output of echo $LIST to gerp?
Yup. Whenever you see text surrounded by "$( )" or backticks ( ` ), the shell knows to execute the text inside as a command, and then replaces the whole string with the command's results. So, as a simple example:
Code:
date_output=$( date )
would be equivalent to
date_output=Sun Sep 25 02:10:29 CDT 2005
(assuming that was the current time)
By echoing $LIST, and piping it through grep, the script can filter out unwanted files. You can do any number of levels of piping; anything you can do from the command line is legal. Say we wanted the month from the above output (date has an option for this, but just to illustrate):
And also, could you explain that list thing you said
Sure, regular expressions are a pattern matching scheme similar to wildcards. It usually causes some confusion because regular expressions and shell wildcards use common symbols for similar, but not exactly the same meaning. To give you an idea, I'll show you some examples to compare between regular expressions and shell wildcards.
Regular expressions (REs) and shell wildcards share the square bracket format ( [ ] ). In both, it means "match any character in this set of characters".
The asterisk (*) in REs says to match zero or more occurrences of the previous pattern. In the shell, it means match zero or more of anything. So, consider this pattern "[a-z]*". For REs, that means "match zero or more occurrences of any lowercase character." For shell wildcards it means "match a single lower case character followed by anything, or nothing (including numbers, punctuation, etc.)."
The question mark (?) in REs says to match one or zero occurrences of the previous pattern. In the shell, it means match exactly one of any character. So, using a slightly modified version of the earlier pattern: "[a-z]?", as an RE, that expression means "match zero or one lowercase letter." For the shell, it means "match a lowercase letter followed by another character of any type."
The last one I'll bring up is the period (.). In REs, that means "match any character" and in the shell's wildcard expansion, it's treated as a literal period.
You can make some pretty crazy looking expressions in REs. The stuff I mentioned here just scratches the surface. What trips a lot of people up is they see the same symbols used in the shell and other applications, assume they mean the same thing, and get bad results. The frustration is understandable because there seems to be little consistency. Bash supports one interpretation of wildcards, Perl supports others, utility programs (like grep) supports limited regular expressions, etc. It can be a mess at times.
Last edited by Dark_Helmet; 09-25-2005 at 02:37 AM.
Distribution: Slack, FreeBSD,NetBSD, OpenBSD, Open Solaris, Minix
Posts: 172
Original Poster
Rep:
Wow. Thanks for taking the time to give me such a thorough explanation. Since you seem like a good person to ask, could you recommend a good book on shell scripting?
Check out The Linux Documentation Project. Click on the "Guides" link, and there are two that may be of interest to you: "Bash Guide for Beginners" and "Advanced Bash-Scripting Guide." They are both available in different formats. I'm not sure of a printed, bound book to purchase. I'm guessing O'Reilly would have one, and their books are usually to-the-point.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.