0

I have 2 bash script variables defined:

THELINENUMBER="14" # an arbitrary line number, comes from a separate command
NEWLINE="a line/ with@ special! characters<" # arbitrary line with special characters, comes from separate command

I need to use the line number ${THELINENUMBER} to replace a line in a file called after.txt with ${NEWLINE}. How do I do that? These are some examples I have tried:

sed -i '${THELINENUMBER}s#.*#"/"${NEWLINE}"/"' after.txt
sed -i "${THELINENUMBER}s#.*#"/"${NEWLINE}"/"" after.txt
sed -i "${THELINENUMBER}s/.*/'${NEWLINE}'" after.txt
sed -i '${THELINENUMBER}s,.*,${NEWLINE}' after.txt

I am told that the delimitter is usually a /, but those are present in my line replacement variable, so I can't use those. I tried with # and , but the desired behavior did not change. I am also told that " and ' are supposed to be used to turn off escaping in text (use literal string), but I have not been able to get that to work either. How do I pass in a string parameter into sed that has special characters? I am wondering if I should pass the variable ${NEWLINE} into another built-in function call to add escape characters or something before passing it into sed. Is sed the right tool for the job? I did not find much helpful information looking at the CLI manpages. I use Ubuntu 18.04.

I have referred to these sources in my internet search:

https://stackoverflow.com/questions/11145270/how-to-replace-an-entire-line-in-a-text-file-by-line-number
https://askubuntu.com/questions/76808/how-do-i-use-variables-in-a-sed-command
https://stackoverflow.com/questions/37372047/find-a-line-with-a-string-and-replace-entire-line-with-another-line
robotsfoundme
  • 418
  • 4
  • 18

2 Answers2

1

Use the c (change) command.

By the way, the naming convention for regular shell variables is NOT ALLCAPS, as that may result in accidental collisions with special variables like PATH.

sed "$linenumber c\\
$newline" file
Socowi
  • 25,550
  • 3
  • 32
  • 54
  • I tried the command, and it spits out the correct result to the terminal. I looked at the actual text file, and I don't see any changes to the file saved on disk. How do I make the change persistent to the file? I was using the operator `>` and the file would simply be wiped. – robotsfoundme Sep 20 '21 at 11:28
  • 1
    @robotsfoundme Add the `-i` option to tell `sed` to modify the original file "in-place". – Gordon Davisson Sep 20 '21 at 18:41
0

Try

sed -i "${THELINENUMBER}s#.*#${NEWLINE}#" after.txt

this works because:

  1. You require " enclosing the entire sed command instead of backtick so that the variables are expanded
  2. No other quotes or backticks are needed to escape " in the variables as there aren't any: there are no literal (escaped) quotes inside the variables
  3. An alternate separator (such as #) is required due to the / inside the NEWLINE variable.
SamBob
  • 849
  • 6
  • 17