3

In a file (file1.txt) I have /path1/|value1 (a path, followed by a value). I need to find the line containing that (unique) path and then change the value. So the line should end up as: /path1/|value2.

The challenge is that the /path1/, value1 and value2 parts are both contained within variables.

When I don't use a variable, I can use (thanks to this page):

sed '/path1/s/value1/value2/g' file1.txt > copyfile1.txt

(This creates a copy of the original file which I can later overwrite the original file using mv.)

This is just searching for path1. To search for /path1/ I can use:

sed '/\/path1\//s/value1/value2/g' file1.txt > copyfile1.txt

Using the answers to this question about extracting a substring I can put the /path1/, value1 and value2 parts into variables.

So my current code is:

sed '/'"${PATH}"'/s/'"${PREVIOUS_VALUE}"'/'"${NEW_VALUE}"'/g' file1.txt > copyfile1.txt

But this does not work because the PATH variable contains forward slashes. Using information from here I have tried first doing a substitution like this:

FORMATTED_PATH=$(echo "${PATH}" | sed 's/\//\/\//g')

first, and then used FORMATTED_PATH instead of PATH but then the find and replace does not work (no error messages, new file is empty). And in the logging FORMATTED_PATH = //path1// (which I think is correct).

How can I do this find and replace using variables containing forward slashes?

(I found out via this answer that I needed to close the single quote, use double quotes around the variable and then open the single quote again. But this does not help with the forward slashes.)

Community
  • 1
  • 1

3 Answers3

1

The code was so nearly right. Instead of:

FORMATTED_PATH=$(echo "${PATH}" | sed 's/\//\/\//g')

I should have had:

FORMATTED_PATH=$(echo "${PATH}" | sed 's/\//\\\//g')

This then produces the correct logging of: FORMATTED_PATH = \/path1\/

1

awk will work too:

awk -F '|' -v path="$paht" -v new="$new_value" '{
    if ($1 == path) {print path FS new}
    else {print}
}' file1.txt > copyfile1.txt

Also, don't use all-caps for your shell variables: you have wiped out your shell's PATH variable used to find programs..

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
1

Usually the sed's s command (as in s///) supports using separators other than /. For example:

$ echo '/path1/|value1' | sed 's,\(/path1/|\).*,\1value2,'
/path1/|value2
$

This is very convenient when dealing with file pathnames which include / chars.

pynexj
  • 19,215
  • 5
  • 38
  • 56