Inside different htm.gz, html.gz and php.gz web files I have images and the ones in .jpg format have name with space instead of "-", but in /images/ directory where all images are located they have "-" instead of space

In html file I have "<img class="photo" width="400" height="600" src="/images/red roses in summer 54.jpg" alt="">

And in directory "/images/" all are listed fine with "-" between words like this "red-roses-in-summer-54.jpg"

So, what I want is a bash command/script that searches in all htm.gz, html.gz and php.gz files inside /var/www/domain.com and find all .jpg images and replace space with "-". So from /images/red roses in summer 54.jpg to have /images/red-roses-in-summer-54.jpg

Server is running on centos 7 if it's important.

  • Do you mean you want to change the names within the zipped (tar?) archives? Commented Jun 8, 2016 at 15:08
  • Have you even attempted to script it yourself, or are you asking for a service?
    – Peschke
    Commented Jun 8, 2016 at 15:20
  • @MichaelVehrs yes, if possible. Commented Jun 8, 2016 at 15:29
  • @Peschke Well, if I have the right commands I can make a bash script in linux, but if you can build it I'm fine to pay if price is reasonable Commented Jun 8, 2016 at 15:30
  • @user2627132 - No pay necessary, I was just curious.
    – Peschke
    Commented Jun 8, 2016 at 15:31

2 Answers 2


Ideally, this should be done in a language like perl or python which have good HTML parsing libraries. But if you want to do it in a shell script, you can install the xml2 package, which provides tools called html2 and 2html for converting HTML to and from a flat-file format suitable for use with line-oriented tools like sed, grep, awk, etc.

It also contains similar tools for working with XML and CSV files.

Then you can use sed to transform spaces on matching img src lines to dashes. Then convert back to html.

For example, using your sample html line:

$ cat file.html 
<img class="photo" width="400" height="600" src="/images/red roses in summer 54.jpg" alt="">

$ html2 < file.html  | sed -e '\:/img/@src=/images/: s/ /-/g' | 2html 
<html><body><img class="photo" width="400" height="600" src="/images/red-roses-in-summer-54.jpg" alt="">

Redirect the output from that to, e.g., file.new.html. and then mv -f file.new.html file.html if you want to replace the original file with the modified version. I very strongly recommend keeping a backup copy of the original files so that you can revert to a known-good starting point if you make a mistake.

BTW, the flat-file format produced by html2 looks like this:

$ html2 < file.html 
/html/body/img/@src=/images/red roses in summer 54.jpg

xml2 is packaged for Debian and Ubuntu and probably other Linux distros. If it's not available pre-packaged for your unix, you can find the source code at the link above.

There are many ways to make these changes in lots of files. Here's a simple for loop example.

for htmlfile in *.html ; do

   html2 < "$htmlfile" |
       sed -e '\:/img/@src=/images/: s/ /-/g' |
       2html > "$htmlfile.new" \
   && mv -f "$htmlfile.new" "$htmlfile"


WARNING: test that this does what you expect before running it on lots of HTML files. And keep a backup of the originals. If the HTML in your files is not completely valid HTML (i.e. if it won't pass a HTML syntax checker) then html2 | ... | 2html could make your html files even more broken than they already are.

If there are too many files, or the files are in multiple subdirectories, you'll have to use find ... -exec. There are countless examples of using find here on this site.

  • I need this to work on approx 200000 pages, so doing 1 image by 1 isn't the case. Maybe a way to search in each page for any .jpg image that is in tag src="/images/ Commented Jun 9, 2016 at 6:02
  • Anything you do to one file can be done to 200000, or any number of files. Use a for loop. or find ... -exec
    – cas
    Commented Jun 9, 2016 at 6:05
  • soory to bug with my noob question, but can you please give more details. I have approx 200000 files that the bash script/command need to look after. About find command, this is one: find /var/www/domain.com -type f ! ( -name '.yml' -o -name '.cgi' -o -name '.pl' -o -name '.db' -o -name '.sqlite' -o -name '.feed' -o -name '.com' -o -name '.xml' -o -name '.gz' -o -name '.txt' -o -name '.pdf' -o -name '.js' -o -name '.css' -o -name '.ico' -o -name '.gif' -o -name '.png' -o -name '.jpg' -o -name '.jpeg' ) -exec Commented Jun 9, 2016 at 8:20
  • I installed xml2 package for centos but above bash script gives me error " 2html: command not found" Any suggestion from here? Commented Jun 9, 2016 at 18:51
  • is 2html actually in the xml2 package in Centos? maybe the centos devs decided to split it into two packages. i don't know, I don't use centos.
    – cas
    Commented Jun 9, 2016 at 22:08

I've found something but doesn't work well:

find /var/www/domain.com -type f ! \( -name '*.db' -o -name '*.sqlite' -o -name '*.feed' -o -name '*.com' -o -name '*.xml' -o -name '*.gz' -o -name '*.txt' -o -name '*.pdf' -o -name '*.js' -o -name '*.css' -o -name '*.ico' -o -name '*.gif' -o -name '*.png' -o -name '*.jpg' -o -name '*.jpeg' \) -maxdepth 1 -exec sed -e '\:/img/@src=/images/: s/ /-/g' {} \;

This opens all files, looks inside, BUT doesn't change anything. Any suggestions?

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .