Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sed substitution with Bash variables

I am trying to change the values in a text file using sed in a Bash script with the line,

sed 's/draw($prev_number;n_)/draw($number;n_)/g' file.txt > tmp 

This will be in a for loop. Why is it not working?

like image 404
csta Avatar asked Oct 06 '11 21:10

csta


People also ask

How do you use variables in sed substitution?

First, choose a delimiter for sed's s command. Let's say we take '#' as the delimiter for better readability. Second, escape all delimiter characters in the content of the variables. Finally, assemble the escaped content in the sed command.

Can you use variables in sed?

The shell is responsible for expanding variables. When you use single quotes for strings, its contents will be treated literally, so sed now tries to replace every occurrence of the literal $var1 by ZZ .

Can you use sed in a bash script?

Bash allows you to perform pattern replacement using variable expansion like (${var/pattern/replacement}). And so, does sed like this (sed -e 's/pattern/replacement/'). However, there is more to sed than replacing patterns in text files.

How do you expand a variable in sed?

Just use double quotes instead of single quotes. You'll also need to use {} to delimit the number_line variable correctly and escape the \ , too.


2 Answers

Variables inside ' don't get substituted in Bash. To get string substitution (or interpolation, if you're familiar with Perl) you would need to change it to use double quotes " instead of the single quotes:

# Enclose the entire expression in double quotes $ sed "s/draw($prev_number;n_)/draw($number;n_)/g" file.txt > tmp  # Or, concatenate strings with only variables inside double quotes # This would restrict expansion to the relevant portion # and prevent accidental expansion for !, backticks, etc. $ sed 's/draw('"$prev_number"';n_)/draw('"$number"';n_)/g' file.txt > tmp  # A variable cannot contain arbitrary characters # See link in the further reading section for details $ a='foo bar' $ echo 'baz' | sed 's/baz/'"$a"'/g' sed: -e expression #1, char 9: unterminated `s' command 

Further Reading:

  • Difference between single and double quotes in Bash
  • Is it possible to escape regex metacharacters reliably with sed
  • Using different delimiters for sed substitute command
  • Unless you need it in a different file you can use the -i flag to change the file in place
like image 89
k.parnell Avatar answered Sep 21 '22 05:09

k.parnell


Variables within single quotes are not expanded, but within double quotes they are. Use double quotes in this case.

sed "s/draw($prev_number;n_)/draw($number;n_)/g" file.txt > tmp 

You could also make it work with eval, but don’t do that!!

like image 20
Paul Creasey Avatar answered Sep 21 '22 05:09

Paul Creasey