I am writing a rather massive script for a project and one of the issues I am running into before I can complete it is using the sed command.

I am trying to find a line that has (located in cache.php):

$cache_directory = './cache'; 

and replace the information in './cache' with a variable named $new_cache_directory.

One of the problems I am running into is the ./cache exists multiple times. I only want to replace that one line, but I also don't want to "hard code" the line number to "future proof" it.

How can I do that?

2 Answers 2


Try this:

sed -i.bak "s:^.*\(\$cache_directory = \)\('./cache'\):\1$new_cache_directory:" infile
  • This worked with one exception, the $new_cache_directory variable was not passed infile. It shows $cache_directory = '$new_cache_directory'; Commented May 26, 2011 at 5:59
  • @Jason: ok. what is your expected output? Commented May 26, 2011 at 6:04
  • 1
    This is an interactive script so the user is defining $new_cache_directory using printf and read... Basically the variable needs to be passed to the file. So if they answer whackachuck that is what the file shows. Is that a little more descriptive? Commented May 26, 2011 at 6:12
  • @Jason: answer is updated.removed backslash before $new_cache_directory Commented May 26, 2011 at 6:13
  • 1
    Thanks, you just beat me to it! Thanks for all of your help! Commented May 26, 2011 at 6:21

So I guess you want to replace 'cache' with the content of said variable, not with its name:

sed 's#^$cache_directory = ../cache.;#$cache_directory = '$new_cache_directory'#' script.php

So you have different problems to solve: Normally a sed command uses slashes to separate the parts: 's/foo/bar/'. When dealing with paths, this is disturbing, but we can use many delimiters - they are just implicitly declared in following the 's'.

Problem 2 is similar. We often specify the command in single quotes:

sed 'command' file 

But here we have apostrophes around ./cache - what to do? One idea would be, to use

sed "command" file 

instead, which often works, but not here. The apostrophes prevent the Dollar-sign from being interpreted, but quotes wouldn't prevent that. Often, you don't even need apostrophes, and can write:

sed s/standart/standard/g sample.txt 

but again, you have $cache_directory as a variable in the command, which would be interpreted. So I just replace the apostrophes with the joker sign, dot, and would be really surprised, if some other expression would match that part: ../cache. like xy/cachei - not very probable, is it?

But you like $new_cache_directory to be replaced with the content of the variable, so I switch masking off with = ', insert the variable, and switch masking on again to finish the command with '#'.

  • Thank you for the well explained thought process, I really do appreciate it when people take the time out to throughly explain something. However, that method didn't work. it displayed the output of the file in terminal. Commented May 26, 2011 at 5:52
  • Well - to generate a file, you usually use sed 'cmd' file.in > file.out, but to replace the file, you use sed -i 'cmd' file. But the latter works just once, so I thought you would like to keep the source, and know about piping the output somewhere. Commented May 26, 2011 at 12:38

You must log in to answer this question.

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