Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
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.
My music folders are a complete mess due to upper/lowercase, in the folders itself underscores or spaces. Therefor I want all files and folders to be lowercase and without underscores. These commands I got from a howto burning audio cd's from commandline. I wanted to alter their form so they could do what I want them to.... (but in the end didn't)
Changing upper- to lowercase:
for i in *.[Mm][Pp]3; do mv "$i" `echo $i | tr '[A-Z]' '[a-z]'`; done
That's works. But what if I want to change letters from directories and its subdirectories?
Changing spaces to underscores:
for i in *.mp3; do mv "$i" `echo $i | tr ' ' '_'`; done
Works for me too. But when I want underscores to be replaced with spaces, the command doesnt work.
You may probably think "so what?", but what I am aiming at is, how exactly does this syntax (or what such commands are called) go to work? Because swapping " " with "_" in the latter command, dosnt work. I tried reading manual pages, but they didnt offer me anything understandable, at least from what I could find. Googling only did raise my level of frustration, so my hope's on you
My question thusly is: Could anyone explain these commands? For example: what the "i" stands for and the "tr" and the other things.
Try this one :) ... I use it in combination with find.
find /path/to/linuxify -exec namecheck.sh {} \;
Code:
namecheck.sh
#!/bin/bash
# for this script we don't want " " as a separator
# so we don't confuse mv with "multiple arguments"
IFS=$'\n'
name=$1
newname=$name
# check for, and replace upper case letters if applicable
echo $name | grep -e [[:upper:]+] > /dev/null
if [ "$?" = "0" ]
then
newname=`echo $name |tr [:upper:] [:lower:]`
fi
# check for and delete leading spaces
echo $newname | egrep "^ +" > /dev/null
if [ "$?" = "0" ]
then
newname=`echo $newname | sed "s/ *//"`
fi
# check for and delete leading spaces as presented by find
echo $newname | egrep "\./ +" > /dev/null
if [ "$?" = "0" ]
then
newname=`echo $newname | egrep "\.\/ +" | sed "s/ *//" `
fi
# check for and delete trailing spaces
echo $newname | egrep " $" > /dev/null
if [ "$?" = "0" ]
then
newname=`echo $newname | sed "s/ *$//"`
fi
# check for and delete other non-welcome characters
echo $newname | grep [\(\)\&\'\!] > /dev/null
if [ "$?" = "0" ]
then
newname=`echo $newname | sed "s/[\(\)\&\'\!]/_/g" `
fi
# check for and replace all other spaces with "_"
echo $newname | egrep " " > /dev/null
if [ "$?" = "0" ]
then
newname=`echo $newname | sed "s/ /_/g"`
fi
# should we have generated a caravan of underscores
# this should take care of it
echo $newname | egrep "_+" > /dev/null
if [ "$?" = "0" ]
then
newname=`echo $newname | sed "s/__*/_/g"`
fi
# "_-_" ... another artefact to be taken care of
echo $newname | grep "_-_" > /dev/null
if [ "$?" = "0" ]
then
newname=`echo $newname | sed "s/_-_/_/g"`
fi
# if there were modifications, commit them
if [ "$name" != "$newname" ]
then
echo "moving " $name $newname
mv "$name" "$newname"
fi
Thanks for both the replies. Tinkster, when I make it an executable shellscript, then it says
line 64: unexpected EOF while looking for matching ``'
line 73: syntax error: unexpected end of file
for all it finds. Don't know why it does that, since I cut n paste your code. Well, I am trying to sort things out.
for i in *.[Mm][Pp]3; do
mv "$i" `echo $i | tr '[A-Z]' '[a-z]'`;
done
For each file whose name ends in .mp3 (irrespective of the case of the m or the p), execute the next line, substituting $i with the name of the file in question.
So once we're in the middle line, we're doing something like
This is using the mv command to rename MyFile.mp3. The new name is generated by the code between the backticks (`). Backticks are special - when the shell sees those, it spawns off another shell in which the commands inside the backticks are executed, and then substitutes the output of these commands back into the original command line. So, the new filename is generated by:
Code:
echo MyFile.mp3 | tr '[A-Z]' '[a-z]'
echo "MyFile.mp3" simply outputs "MyFile.mp3". This is the 'piped' (|) into the tr program. tr is a simple character translation program (see man tr). The first argument specifies what to look for, and the second what to replace it with. [A-Z] means any capital letter. [a-z] means the small version of whatever we found in the first one. So, tr outputs "myfile.mp3", and this is substituted back into the original line to give:
Code:
mv "MyFile.mp3" "myfile.mp3"
Which is what we wanted. Remembering the for loop, this is going to happen for each file ending in .mp3, or .MP3, or .mP3, or .Mp3.
For detail on the nitty-gritty of how bash works, see the bash reference manual. It's long and technical, but comprehensive. For more information on regular expressions (things like [A-Z]) there is a thick O'Reilly book on the subject. You may find a less in-depth explanation of regexes in any good perl book (I've used Randall Schwartz's "Learning Perl").
Oh, and the classic beginner's "gotcha" for stuff like this is forgetting those double-quotes everywhere. This is necessary to deal with filenames with spaces in. Otherwise, one might end up with a command line such as "mv My File.mp3 myfile.mp3" which is not what we wanted: there are three filenames there ("My","File.mp3","myfile.mp3"). However, "mv "My File.mp3" myfile.mp3" is fine (please excuse my nested quote marks).
Originally posted by tct1501 Thanks for both the replies. Tinkster, when I make it an executable shellscript, then it says
line 64: unexpected EOF while looking for matching ``'
line 73: syntax error: unexpected end of file
for all it finds. Don't know why it does that, since I cut n paste your code. Well, I am trying to sort things out. :study:
|--j@slackmagick bash 2.05b (1) Fri Nov 14 22:39:32
|--~/Fooagain >> namecheck.sh
/home/j/bin/namecheck.sh: line 65: unexpected EOF while looking for matching ``'
/home/j/bin/namecheck.sh: line 75: syntax error: unexpected end of file
I think it's actually at line 39, though - I'm too brain dead at the moment to figure it out but, when I slap a single-quote on the other side of the backslash in -- &'\ ' --- (Weird. Why does LQ eat the backslash in this if the single quotes are right next the the backslash?) just to close it off, it runs and fixes one of my three test files.
Code:
# check for and delete other non-welcome characters
echo $newname | grep [\(\)\&'\!] > /dev/null
Actually, I bet that's what happened - the board ate part of your code even though it was [ code ]-ed, Tink - it ate my backslash even in [ code ] unless I put a space in - '\ '
It hadn't occured to me that LQ might be
changing my input, I never copied the stuff
from the board back - but you are right.
I copied it back now, and diffed it against
my original ... the board has swallowed the
escaping \ after & and before ' in two lines.
Line 39 and 42 ...
Thanks for posting that - works like a charm now. It doesn't catch all the craziness I threw at it but would handle the usual misnamed stuff. Gives me something to play with, too.
We should have a 'post your handy shellscripts here' thread and have it stickied. I'd live in that thread. Teach bash scripting the practical and interactive way and pick up all kinds of nifty tools.
Incidentally, that's quite dangerous that the [ code ] tags don't fully work. If the wrong thing got altered in the wrong script and someone just copied and pasted, there could be unpleasant results. Is clicking on Jeremy's profile and then email address or something the correct way to inform him? He sees much of what is posted in the threads, but not everything, I imagine.
Originally posted by digiot
Thanks for posting that - works like a charm now. It doesn't catch all the craziness I threw at it but would handle the usual misnamed stuff. Gives me something to play with, too. :D
Pleasure mate, if you make major enhancements
post it back ;) ... I couldn't figure out how to escape
a few characters ;}
[quote[
We should have a 'post your handy shell-scripts here' thread and have it stickied. I'd live in that thread. Teach bash scripting the practical and interactive way and pick up all kinds of nifty tools.
[/quote]
Sounds like a good scheme to me :)
Quote:
Incidentally, that's quite dangerous that the [ code ] tags don't fully work. If the wrong thing got altered in the wrong script and someone just copied and pasted, there could be unpleasant results. Is clicking on Jeremy's profile and then email address or something the correct way to inform him? He sees much of what is posted in the threads, but not everything, I imagine. :)
Well, in this case it was harmless, because it didn't
work. But I imagine that there might be cases where
it does It might be harmful in other cases, and giving
Jer a yell seems sensible to me.
So, people, thanks for all the provided help . I havent managed to make the script work, though, but I am trying. I dont find myself on the same level of linux-experience as you do. I got all the info i asked for. I drink a beer to that
Distribution: Debian, Red Hat, Slackware, Fedora, Ubuntu
Posts: 13,602
Rep:
I finally got a chance to look at this. Unfortunately it's a bit more complicated than I had anticipated. I'll see if I can come up with a fix, but it's non-trivial and may not happen for a while. Sorry.
Originally posted by jeremy
I finally got a chance to look at this. Unfortunately it's a bit more complicated than I had anticipated. I'll see if I can come up with a fix, but it's non-trivial and may not happen for a while. Sorry.
Hi Jeremy,
thanks for all the efforts!
As for the fix, don't worry too much,
at least it's documented now ;)
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.