I cannot for the life of me figure this out.
I have a sed command being executed here (it's an M1 Mac, which I know has a different version of sed than GNU sed, which could be the problem? But i need the command to act the same on Linux/Windows/Mac:
firstString="SQLITE_KEY=\"?.*\"?[^\w\d]"
secondString="SQLITE_KEY=\"?${SQLITE_KEY_GENERATED}\"?"
sed -i '' -r "/SQLITE_KEY/ s/${firstString}/${secondString}/" .env
I have a set of environment variables in another file, and these are injected into the .env file:
SQLITE_KEY=zCokzf3aVzS0T7cH3mJiyrqUBK5YpETwqVf4tg==
However when I run it, I get an error like this.
sed: 1: "/SQLITE_KEY/ s/SQLITE_K ...": bad flag in substitute command: 't'
The goal here is to take the environment variables from the source file, and inject them into the .env file where SQLITE_KEY is. The "bad flag" warning changes letters every time, so I'm suspecting it's something to do with the formatting of the password.
What am I doing wrong?
You have a syntax conflict involving double-quotes (").
secondString has escaped '"'.
Those are then interpreted by the shell command after the variable substitution for sed.
So ... you need to replace the outside double-quotes by single-quotes on the sed, in this way:
eval sed -i \'\' -r \'/SQLITE_KEY/ s/${firstString}/${secondString}/\' .env
This way, the double-quotes will be correctly carried thru into the .env file.
Related
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
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
Try
sed -i "${THELINENUMBER}s#.*#${NEWLINE}#" after.txt
this works because:
You require " enclosing the entire sed command instead of backtick so that the variables are expanded
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
An alternate separator (such as #) is required due to the / inside the NEWLINE variable.
So I have seen this question: Replace complete line getting number from variable
which is pretty similar, but in my case I am trying to use multiple variables: one for the line number [lineNo], one for the text to replace [transFormatted] and the file to which it should be looking in [OUTPUT_FILE] I've tried dozens of combinations to try to get it to recognize all these variables but nothing seems to work. It's unhappy no matter which way I try. What am I doing wrong?
sed -e '${lineNo}s/.*/${transFormatted}/' < $OUTPUT_FILE
Single quotes inhibit parameter expansion.
sed -e "${lineNo}s/.*/$transFormatted/" < "$OUTPUT_FILE"
You have to use double quotes for the variables to be expanded from the shell environment.
I'm trying to:
sed -i s/installpath/"$INSTALL_PATH"/ /tmp/myscript.conf
when $INSTALL_PATH is just a string everything works. but if install path is an actual path (II guess the '/' char is the problem) like /home/ubuntu/install_script. then It breaks with the following error message:
sed: -e expression #1, char 16: unknown option to `s'
btw: I tried without the "" around $INSTALL_PATH. didn't work
Thanks for the help!
It is likely that $INSTALL_PATH contains slashes, which means that they will be interpreted by sed as part of the s/pattern/replacement/ construct. To avoid this, you should use a different separator, for example ~:
sed -i "s~installpath~$INSTALL_PATH~" /tmp/myscript.conf
I have also wrapped the whole sed line in quotes rather than quoting one section. In general, it's a good idea to do this as it prevents other characters from being interpreted by the shell. Normally single quotes are used but if shell variables are to be expanded, use double quotes.
You don't have to use / as the delimiter in sed commands. Use something that's less likely to occur in a filename, e.g.:
sed -i s^installpath^"$INSTALL_PATH"^ /tmp/myscript.conf
If you're careful with quoting you can use other characters which are even less likely to exist inside a filename:
sed -i "s|installpath|$INSTALL_PATH|" /tmp/myscript.conf
The pipe is outright illegal in Windows paths, and on Linux it's a really bad idea and unlikely to occur in the wild.
I want to use sed for replacing multiple files from bash script.
When I call it from bash I get below error
DEBUG FLOW:-
FILELIST='/tmp/components/ab.sql /tmp/b.sql'
+ SUBSTITUTE_STRING=abc
+ sed -i.bak -e s/abc/xyz/g '/tmp/components/ab.sql /tmp/b.sql': No such file or directory
however when I used this command directly on terminal it executes successfully
sed -i.bak -e s/abc/xyz/g /tmp/components/ab.sql /tmp/b.sql
The difference from terminal and script is of quotes around the file.
I have tried defining File list variable without quotes as well
kindly suggest
Instead of saying:
FILELIST='/tmp/components/ab.sql /tmp/b.sql'
make it an array by saying:
FILELIST=(/tmp/components/ab.sql /tmp/b.sql)
and while invoking say:
sed -i.bak -e "s/abc/xyz/g" "${FILELIST[#]}"
If you look at the debug flow, it'd be evident that the shell parses the filenames as a single token ('/tmp/components/ab.sql /tmp/b.sql') which causes the No such file or directory error.
I believe this may be a simple question, but I've looked everywhere and tried some workarounds, but I still haven't solved the problem.
Problem description:
I have to replace a character inside a file and I can do it easily using the command line:
sed -e 's/pattern1/pattern2/g' full_path_to_file/file
But when I use the same line inside a bash script I can't seem to be able to replace it, and I don't get an error message, just the file contents without the substitution.
#!/bin/sh
VAR1="patter1"
VAR2="patter2"
VAR3="full_path_to_file"
sed -e 's/${VAR1}/${VAR2}/g' ${VAR3}
Any help would be appreciated.
Thank you very much for your time.
Try
sed -e "s/${VAR1}/${VAR2}/g" ${VAR3}
Bash reference says:
The characters ‘$’ and ‘`’ retain their special meaning within double quotes
Thus it will be able to resolve your variables
I use a script like yours... and mine works as well!
#!/bin/sh
var1='pattern1'
var2='pattern2'
sed -i "s&$var1&$var2&g" *.html
See that, mine use "-i"... and the seperator character "&" I use is different as yours.
The separator character "&" can be used any other character that DOES NOT HAVE AT PATTERN.
You can use:
sed -i "s#$var1#$var2#g" *.html
sed -i "s#$var1#$var2#g" *.html
...
If my pattern is: "test#email.com" of course you must use a seperator different like "#", "%"... ok?