Scott Rowley
Scott Rowley

Reputation: 484

Bash, find and replace - re-use with variable?

I'm building a script in bash that goes and finds references to other files (such as a reference in an html file to an img source (image.jpg)

The problem is that I'm using sed to replace all instances that contain (in this example) "/some/random/directory/image.jpg"

The "some/random/directory/image.jpg" is going to be differen every single time so when it comes to my sed line I need to use regex, but in order to find the line to replace I need to include image.jpg.

so for example my sed line would be something like

sed 's/\/some\/random\/directory\/image.jpg/images\/image.jpg/g'

But how do I get the end of whats in the find and put it into the replace? (In this example it would be image.jpg. Is there some way to make that a variable?

Here's my script as it stands now:

#!/bin/bash

cd /home/username/www/immrqbe/

for file in $(grep -rlI ".jpg" *)
do
sed -e "s/\".*\/.*.jpg//ig" $file > /tmp/tempfile.tmp
mv /tmp/tempfile.tmp /home/username/www/immrqbe/$file
done

This obviously isn't functional complete as I need help with it but you get the idea of how I'd like to have it complete.

Upvotes: 1

Views: 2354

Answers (2)

Tim Pote
Tim Pote

Reputation: 28059

What you're looking for is called a Backreference in the world of regular expressions. You want to refer back to a previously matched string.

There are a couple of ways to do this with sed, but what you want to use is the grouping mechanism: \( and \). Anything sed finds between \( and \) will be put into a group and you can refer back to that group using \n where n is the number of the group that you want to use, from left to right.

So, in your example, you want:

sed 's/".*\/\(.\+\.jpg\)"/\1/ig' file

Your filename will be in the \(.\+\.jpg\) group and you can then refer to it using \1 in the replacement section.


As a side note, notice that, as long as you don't want the shell to expand a variable in your quoted string, you can use single quotes and avoid escaping the double quotes in your pattern.

Upvotes: 5

Neil
Neil

Reputation: 55422

Use parentheses to capture the match and then refer to it using backslash.

sed -e 's/".*\/\(.*.jpg\)/\1/ig'

Upvotes: 3

Related Questions