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.
I am looking for a bash script that would help me rename a bunch of pics that I had on a Winblows machine. The files look like this
/granny/grannypics_(1001).jpg
I would like to rename them to something like this
/granny/grannypics.1001.jpg
I just recently switched from Winblows to ubuntu, not a noob but not a pro either, not scared to use the cli.
I have found a bash script that takes all the blank spaces out of file names I don't know if it can be modified to do what was explained above, but here it is if it helps
for i in `find . | tr "[:blank:]" "+" | grep "+"`; do echo "Changing Directory: " `echo $i | sed -r 's/\+/\\ /g'` " to " `echo $i | tr "+" "_"`; mv "`echo $i | sed -r 's/\+/\\ /g'`" `echo $i | tr "+" "_"`; done
If someone could explain to me how this script works or how to modify it to do the above I would be thankful. I could go in and edit each picture which would not be a big deal if there where one or two pics but I have over 10,000 to do so it would be a real pain one by one
Let me thank who ever responds to this thread in advance
You have to encapsulate the file name in quotes because the parentheses have special meaning to the shell and most commands. The echo just says "display this". What is being displayed is "piped" (the veritical bar) into the first sed command.
The first sed is doing a (s)ubstitute. The format of substitute is forward slash, search pattern, forward slash, replacement pattern, forward slash. Our search pattern is _( but since ( is a special charater it has to be "escaped" with the backslash so the pattern becomes _\( instead. The replacment is the dot. We then have to pipe (vertical bar again) into another sed to substitute the ) with nothing. Again it has to be escaped so pattern becomes \). Since we aren't actually replacing that with anything we just put in the final forward slash (make sure there is no space between it and the other forward slash.
The rest of it is to encapsulate it in a for loop to make sure it does this for multiple files rather than just the grannypics_(1001).
Code:
for OLDNAME in `ls *jpg`
do NEWNAME=`echo "${OLDNAME}" |sed s/_\(/./ |sed s/\)//`
mv $OLDNAME $NEWNAME
done
This for loop sets OLDNAME as the variable name for each of the pictures presented by "ls *jpg" because we put backticks (not single quotes) around ls *jpg which means execute the command then use only its output (sort of a reverse pipe).
We then use the original command above but substitute the variable name for grannypics_(1001).jpg. We set this as a variable called NEWNAME. (Note the backtick usage again).
Finally we tell it to move the file from its old name to its new name.
The "for", "do" and "done" are required keywords of the loop. The "for" defines each item to do the loop on. The "do" specifies what to do to each item (this can be multiple lines long and can contain other loops and if/then conditionals). The "done" lets it know the "do" is complete.
Prior to actually running the above try doing:
Code:
for OLDNAME in `ls *jpg`
do NEWNAME=`echo "${OLDNAME}" |sed s/_\(/./ |sed s/\)//`
echo oldname is $OLDNAME and newname is $NEWNAME
done
This will simply show you what it gets for each variable rather than actually moving anything. Once you are sure it has the correct variable values you want then you can run the original for loop above.
Your original script is doing translations and other things but is essentially the same thing. It uses i ($i) as the variable name. The variable name is abitrary. You just have to remember whatever you name it that you call it by that name (e.g. "for billybob in" would require you to use $billybob within the do/done.) Also note the special usage of variable ${billybob}. This is the same as $billybob but insures that if you have anything AFTER the variable name that you want to append that it doesn't think it is PART of the variable name.
Here is another way:
for file in granny*; do
> mv -v "$file" "${file//[()]/}"
> done
Double quotes are used so that the () character don't start a subshell in bash. This example points out that you can use character classes in filename expansion.
Our search pattern is _( but since ( is a special charater it has to be "escaped" with the backslash so the pattern becomes _\( instead.
In `sed' characters `(' and `)' doesn't have a special meaning, but escaped ones '\(', '\)' -- does. On the contrary, in `Perl' parentheses -- is a grouping char's, and escaped ones -- not.
In `sed' characters `(' and `)' doesn't have a special meaning, but escaped ones '\(', '\)' -- does. On the contrary, in `Perl' parentheses -- is a grouping char's, and escaped ones -- not.
Cheers!
Lets put it this way - without escaping the parentheses in the sed usage I listed it does NOT work. If you'd rather say they need to be escaped because of the shell rather than sed have at it.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.