What went wrong with this very short shell script?

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Locked
AwaitingUserInput

What went wrong with this very short shell script?

Post by AwaitingUserInput »

I just wrote another post similar to this. I am trying to learn basic scripting to handle large amounts of files. For this task, I have a directory with files ending in .jpg. I want to change the file extension from .jpg to .png.

Here is the script I used:

Code: Select all

for orig_name in *.jpg ; do b=$(basename $orig_name) ; mv $orig_name $b".png" ; done
Instead of replacing .jpg with .png, it just added .png to the end of the file name.

Example:

I had foo.jpg
I wanted to rename it to foo.png
Instead it renamed it to foo.jpg.png

What did I do wrong and why?

I'm not trying to get this script to work so much as I am trying to learn the reasons it didn't work so future ones will be better.
Last edited by LockBot on Wed Dec 28, 2022 7:16 am, edited 1 time in total.
Reason: Topic automatically closed 6 months after creation. New replies are no longer allowed.
cholq

Re: What went wrong with this very short shell script?

Post by cholq »

If you look at what basename actually does:

Code: Select all

 basename --help
Usage: basename NAME [SUFFIX]
or: basename OPTION... NAME...
Print NAME with any leading directory components removed.
If specified, also remove a trailing SUFFIX.


So, the command without any extra parameters simply removes the path prior to the name of the file. If I type the following:

Code: Select all

 basename ~/Pictures/palemoon.png 
I get "palemoon.png"

If I type:

Code: Select all

basename ~/Pictures/palemoon.png .png
then I get the answer you were looking for, which is just "palemoon", without the file extension.
ganamant
Level 4
Level 4
Posts: 384
Joined: Sun Mar 29, 2015 4:08 pm

Re: What went wrong with this very short shell script?

Post by ganamant »

You do not need basename at all for a ting like this. You will be fine with parameter substitution.
I'm assuming you don't use spaces in your names (you shouldn't, by the way), but if you do, double quote the variable calls.

Code: Select all

for i in *.jpg; do j=${i%jpg}png; echo mv $i $j; done
When you are sure the script does what you need, remove the 'echo' and let mv do it's job.
parsma

Re: What went wrong with this very short shell script?

Post by parsma »

In this particular case, even though you might not have any use for the info, it is easier to use the rename Perl script.
Do:

Code: Select all

which rename
...to see if you have it. After that it's just a matter of:

Code: Select all

man rename
...to get going.
It's something like:

Code: Select all

rename 's/\.jpg/\.png/' *.jpg -n
The -n option is a safety valve, so to speak. It will make the script print what would happen if you didn't include it, as opposed to actually doing it.
I use it all the time for stuff I need done.
Locked

Return to “Scripts & Bash”