Executing Sed Command - linux

When I run the command
sed -e "s/$1/#root#The-Three-Little-Pigs-Siri-Proxy/" -i gen_certs.sh
I Get the following error. I am trying to replace the text $1 with the other below in the same file, not creating a new one just modifying the current one.
sed: -e expression #1, char 0: no previous regular expression
Any ideas what could be causing the error and how to fix it?
OS: Ubuntu 10.10 32 bit

$1 will expand to a null-string('') if it's in double-qouted string.
You can use single quote to keep the literal value of$1:
sed -e 's/$1/#root#The-Three-Little-Pigs-Siri-Proxy/' -i gen_certs.sh

You need to escape the pattern: sed -e "s/\$1/#root#The-Three-Little-Pigs-Siri-Proxy/" -i gen_certs.sh, since $1 denotes a back reference in sed (presuming you want to replace the string $1 in your input, right?)

Related

How to set sed command correctly

When I try following command, I'd like to rewrite sql.
Day='2020/12/1'
Dir=/home/test/data
sql=`cat $Dir"/"$test".sql" | sed -e "s/Day/$Day/g"`
I suffered following errors.
sed: -e expression #1, char 24: unknown option to `s'
Why the s is recognised as option ? why is this command couldnt work well ?
if someone has opinoin, please let me know
Thanks
The problem is with slashes: your variable contains them and the final command will be something like sed "s/string/path/to/something/g", containing way too many slashes.
Since sed can take any char as delimiter (without having to declare the new delimiter), you can try using another one that doesn't appear in your replacement string like below:
sql=`cat $Dir"/"$test".sql" | sed -e "s|Day|$Day|g"`
Also, you would need to use sed -i to update the file in-place, since it looks like that is what you're trying to do.

Sed not working in usual way - Shell scripting

I have two sed command which includes in my cook.sh script. One command is
sed -E -i "s/^(\\\$mainDomain=\")[^\"]+(\";)$/\1$MainDomain\2/" /var/config.php
This is working fine.
But the below command which is almost same. But it is not working.
sed -E -i "s/^(\\\$authURI=\")[^\"]+(\";)$/\1$duo_auth\2/" /var/config.php
That give the below error message
sed: -e expression #1, char 36: unknown option to `s'
Any idea on this ?
The issue is likely due to your replacement variable $duo_auth having a un-escaped /, change the default sed separator from / to ~ as
sed -E -i "s~^(\\\$authURI=\")[^\"]+(\";)$~\1$duo_auth\2~" /var/config.php
Try it without -i for seeing if the replacement is as expected and put it back after confirmation.
Example:-
cat /var/config.php
<?php
$authURI="dev.digin.io";
now setting the variable
duo_auth="http://auth.uri.digin.io:3048/"
Now the replacement, without -i
sed -E "s~^(\\\$authURI=\")[^\"]+(\";)$~\1$duo_auth\2~" /var/config.php
<?php
$authURI="http://auth.uri.digin.io:3048/";
The problem is probably due to $duo_auth containing an unescaped /. This means that the sed editing script will have a syntax error.
You may pick any other character to use as a delimiter in the s/.../.../ command, for example #:
sed "s#....#....#"
Just make sure that you pick a character that is not ever going to turn up in either $duo_auth or $authURI.
While testing, I'd recommend that you avoid using in-place-editing (-i) with sed. Also, the -i switch is horribly non-portable between sed implementations (some requires an argument).
Instead, do the slightly more cumbersome
sed -e "s#...#...#" data.in >data.in.tmp && mv -f data.in.tmp data.in
While testing, check the data.in.tmp file before moving it.

How to use sed with a variable that needs to be escaped

I have a file, and I am trying to use bask to replace all the contents of a substring with a path.
I can use the command:
sed -i s/{WORKSPACE}/$MYVARIABLE/g /var/lib/jenkins/jobs/MY-JOB/workspace/config/params.ini
My config/params.ini looks like:
[folders]
folder1 = {WORKSPACE}/subfolder1
folder2 = {WORKSPACE}/subfolder2
however, when $MYVARIABLE is a path, it fails (containing slashes), the sed command fails with:
sed: -e expression #1, char 16: unknown option to `s'
When I run through it manually, I see that the $MYVARIABLE needs to have it's path-slashes escaped. How can I modify my sed command to incorporate an escaped version of $MYVARIABLE?
There's nothing saying you have to use / as your delimiter. sed will use (almost) anything you stick in there. I have a tendency to use |, since that never (rarely?) appears in a path.
sridhar#century:~> export boong=FLEAK
sridhar#century:~> echo $PATH | sed "s|/bin|/$boong|g"
~/FLEAK:/usr/local/FLEAK:/usr/local/sbin:/usr/local/games:/FLEAK:/sbin:/usr/FLEAK:/usr/sbin:/usr/games:/usr/lib/lightdm/lightdm:/home/oracle/app/oracle/product/12.1.0/server_1/FLEAK
sridhar#century:~>
Using double-quotes will allow the shell to do the variable-substitution.
Just escape the $ sign, and use a different delimiter:
sed -i 's;{WORKSPACE};\$MYVARIABLE;g' your_file

How to use variable in sed command to replace a property value in a property file

i can able to use the below command to change value of target by means of hard coding.
sed -ie s/^target=.*/target=google.com/ url.properties
But if i used variable i am getting error. I dont know how sed commands all working. I only needed to set build system thats it.
url = google.com
sed -ie s/^target=.*/target=$url/ url.properties
the error is
sed: -e expression #1, char 25: unterminated `s' command
The problem may be happening because your URL may contain / which bash interprets as sed syntax, so something like https/www.google.com ends up something like :
sed -ie 's/^target=.*/target=https/www.google.com/' url.properties
I will suggest to delimit any special characters to avoid sed to be confused :
url=google.com
url=`echo $url | sed -e "s/\//\\\\\\\\\//g"` # delimits backslash in URL's
sed -ie "s/^target=.*/target=$url/" url.properties
Two problems:
You can't have spaces in variable assignments in bash
You must quote the sed command (and ideally the url too)
Working example:
url="google.com"
sed -ie "s/^target=.*/target=$url/" url.properties

Environment variable substitution in sed

If I run these commands from a script:
#my.sh
PWD=bla
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
xxx
bla
it is fine.
But, if I run:
#my.sh
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
$ sed: -e expression #1, char 8: Unknown option to `s'
I read in tutorials that to substitute environment variables from shell you need to stop, and 'out quote' the $varname part so that it is not substituted directly, which is what I did, and which works only if the variable is defined immediately before.
How can I get sed to recognize a $var as an environment variable as it is defined in the shell?
Your two examples look identical, which makes problems hard to diagnose. Potential problems:
You may need double quotes, as in sed 's/xxx/'"$PWD"'/'
$PWD may contain a slash, in which case you need to find a character not contained in $PWD to use as a delimiter.
To nail both issues at once, perhaps
sed 's#xxx#'"$PWD"'#'
In addition to Norman Ramsey's answer, I'd like to add that you can double-quote the entire string (which may make the statement more readable and less error prone).
So if you want to search for 'foo' and replace it with the content of $BAR, you can enclose the sed command in double-quotes.
sed 's/foo/$BAR/g'
sed "s/foo/$BAR/g"
In the first, $BAR will not expand correctly while in the second $BAR will expand correctly.
Another easy alternative:
Since $PWD will usually contain a slash /, use | instead of / for the sed statement:
sed -e "s|xxx|$PWD|"
You can use other characters besides "/" in substitution:
sed "s#$1#$2#g" -i FILE
一. bad way: change delimiter
sed 's/xxx/'"$PWD"'/'
sed 's:xxx:'"$PWD"':'
sed 's#xxx#'"$PWD"'#'
maybe those not the final answer,
you can not known what character will occur in $PWD, / : OR #.
if delimiter char in $PWD, they will break the expression
the good way is replace(escape) the special character in $PWD.
二. good way: escape delimiter
for example:
try to replace URL as $url (has : / in content)
x.com:80/aa/bb/aa.js
in string $tmp
URL
A. use / as delimiter
escape / as \/ in var (before use in sed expression)
## step 1: try escape
echo ${url//\//\\/}
x.com:80\/aa\/bb\/aa.js #escape fine
echo ${url//\//\/}
x.com:80/aa/bb/aa.js #escape not success
echo "${url//\//\/}"
x.com:80\/aa\/bb\/aa.js #escape fine, notice `"`
## step 2: do sed
echo $tmp | sed "s/URL/${url//\//\\/}/"
URL
echo $tmp | sed "s/URL/${url//\//\/}/"
URL
OR
B. use : as delimiter (more readable than /)
escape : as \: in var (before use in sed expression)
## step 1: try escape
echo ${url//:/\:}
x.com:80/aa/bb/aa.js #escape not success
echo "${url//:/\:}"
x.com\:80/aa/bb/aa.js #escape fine, notice `"`
## step 2: do sed
echo $tmp | sed "s:URL:${url//:/\:}:g"
x.com:80/aa/bb/aa.js
With your question edit, I see your problem. Let's say the current directory is /home/yourname ... in this case, your command below:
sed 's/xxx/'$PWD'/'
will be expanded to
sed `s/xxx//home/yourname//
which is not valid. You need to put a \ character in front of each / in your $PWD if you want to do this.
Actually, the simplest thing (in GNU sed, at least) is to use a different separator for the sed substitution (s) command. So, instead of s/pattern/'$mypath'/ being expanded to s/pattern//my/path/, which will of course confuse the s command, use s!pattern!'$mypath'!, which will be expanded to s!pattern!/my/path!. I’ve used the bang (!) character (or use anything you like) which avoids the usual, but-by-no-means-your-only-choice forward slash as the separator.
Dealing with VARIABLES within sed
[root#gislab00207 ldom]# echo domainname: None > /tmp/1.txt
[root#gislab00207 ldom]# cat /tmp/1.txt
domainname: None
[root#gislab00207 ldom]# echo ${DOMAIN_NAME}
dcsw-79-98vm.us.oracle.com
[root#gislab00207 ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: ${DOMAIN_NAME}/g'
--- Below is the result -- very funny.
domainname: ${DOMAIN_NAME}
--- You need to single quote your variable like this ...
[root#gislab00207 ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: '${DOMAIN_NAME}'/g'
--- The right result is below
domainname: dcsw-79-98vm.us.oracle.com
VAR=8675309
echo "abcde:jhdfj$jhbsfiy/.hghi$jh:12345:dgve::" |\
sed 's/:[0-9]*:/:'$VAR':/1'
where VAR contains what you want to replace the field with
I had similar problem, I had a list and I have to build a SQL script based on template (that contained #INPUT# as element to replace):
for i in LIST
do
awk "sub(/\#INPUT\#/,\"${i}\");" template.sql >> output
done
If your replacement string may contain other sed control characters, then a two-step substitution (first escaping the replacement string) may be what you want:
PWD='/a\1&b$_' # these are problematic for sed
PWD_ESC=$(printf '%s\n' "$PWD" | sed -e 's/[\/&]/\\&/g')
echo 'xxx' | sed "s/xxx/$PWD_ESC/" # now this works as expected
for me to replace some text against the value of an environment variable in a file with sed works only with quota as the following:
sed -i 's/original_value/'"$MY_ENVIRNONMENT_VARIABLE"'/g' myfile.txt
BUT when the value of MY_ENVIRONMENT_VARIABLE contains a URL (ie https://andreas.gr) then the above was not working.
THEN use different delimiter:
sed -i "s|original_value|$MY_ENVIRNONMENT_VARIABLE|g" myfile.txt

Resources