Changing file extensions in bulk using Git Bash

I just found myself in a situation where I needed to convert 30+ PHP files in to HTML files. Rather than do this manually, I had a look to see if I could do this using command line.

I found this StackOverflow question which gives a few different methods, however they didn’t all work for me as most used ‘rename’ functionality, which I didn’t have.  This answer was the one that worked fine for me using Git Bash on Windows.

To change all .php files in a folder to .html files, run the following command:

find . -name '*.php' -exec sh -c 'mv "$0" "${0%.php}.html"' {} \;

I used explainshell.com to try and make this a bit more human readable:

find .
Search for files within this directory
-name '*.php'
that has the file extenstion .php
-exec{} \;
Do the following for each file found
sh -c ''
This is a shell command
mv
Move (rename) files
"$0" "${0%.php}.html"
I can tell this is taking the original file name, and replacing .php with .html, but can’t figure out what the expression means. Any help?

Forgive me if this is wrong, I’m new to this and trying to learn – please let me know any corrections!

3 Replies to “Changing file extensions in bulk using Git Bash”

  1. I’ll try my best to give a possible explanation for this last part (since I’m not entirely sure either).

    “${0%.php}.html”

    The $ likely tells this to evaluate the following expression, and the 0% may be a regular expression specifying “0 or more characters (using ‘%’ in place of the standard ‘*’)”. I haven’t tested this with the ‘*’ character, but it may be interchangeable with the ‘%’.

  2. Thanks, this post is a real help since Git Bash still doesn’t come with the rename utility (I probably *could’ve* figured out how to do this on my own but I’m lazy :P)

    As for that last expression which you said you can’t figure out what it means,
    I am (regrettably) somewhat knowledgeable of bash,
    so I believe I can help explain a little:

    The ${ } part is a parameter expansion — which inserts shell variables, or in this case, the special positional parameter “$0” (the braces can sometimes be omitted).

    Usually one just inserts the variables as-is & that’s that, but sometimes it is useful to do more complicated things, and there are a number of (IMHO rather unreadable) syntaxes for that. This Bash Manual page lists them: https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

    So the ${parameter%word} syntax actually just does exactly what it needs to do — it trims the word as a suffix from the parameter!

    I will admit I am a little confused by the use of $0, as usually that is the filename of the script being run (or outside of a script, the path to the shell), but I guess the -exec sh -c ‘…’ {} \; overrides that… I really need to use “find” more often, it really does seem quite handy.

Leave a Reply to Art O. Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.