Bash script find and replace string with variable that contains complex special characters without having to escape? [duplicate] - linux

This question already has answers here:
Escape a string for a sed replace pattern
(17 answers)
Closed 3 months ago.
Is there a simpler way to replace a string with a variable literally that contains all complex characters without needing to do character escaping?
complex='~`!##$%^&*()-_=+\|]}{[;:/?.>,<\/*&\#/'
sed -i "s/secret\ =\ \".*/secret\ =\ \"$complex\"/g" ./file.txt
I already know that & \ and / are the problems. I can do all manner of cleaning with sed commands, but is there a simpler way? Is there a way I can literally make sed read that variable as is?
My work around for now is the following, but even this does not work with / properly ...
complex='~`!##$%^&*()-_=+\|]}{[;:/?.>,<\/*&\#/'
psk_bs="$(echo $complex | sed 's/\\/\\\\\\/g')"
psk_bs_amp="$(echo "$psk_bs" | sed 's/\&/\\&/g')"
psk_bs_amp_fs="$(echo "$psk_bs_amp" | sed 's,'/','\/',g')"
sed -i "s/secret\ =\ \".*/secret\ =\ \"$psk_bs_amp_fs\"/g" ./file.txt

I can do all manner of cleaning with sed commands, but is there a simpler way? Is there a way I can literally make sed read that variable as is?
I'm afraid there is not. But character escaping is not as a big deal as you make it seem to be. This'll work just fine:
psk=$(sed 's/[/&\]/\\&/g' <<< $complex)
sed -i "s/secret = \".*/secret = \"$psk\"/g" ./file.txt
With bash 5.2 you don't even need sed for escaping:
psk=${complex//[\/&\\]/\\&}

Related

How to use sed to replace text with a file path? [duplicate]

This question already has answers here:
How to pass a variable containing slashes to sed
(7 answers)
Closed 2 years ago.
I'm writing a bash script where I need to replace text in a file with a specific file path, but my understanding is that sed does not work with specific characters such as /. I'm wondering if there is some way around this?
Here is my script currently:
currentdir="$PWD"
filepathvar="${currentdir}/settings.ini"
sed -i -e "s/filepath/$filepathvar/g" aimparmstest
When I print out filepathvar everything is as I expect it to be, but it seems the fact that filepathvar contains special characters, it gives me the following error:
sed: -e expression #1, char 13: unknown option to `s'
Is there any way around this? Or perhaps another command I can use? I haven't had any success with changing around the parameters. Any help is greatly appreciated.
You can use any character as the separator (the first character). For example:
echo "a/b/c" | sed -e 's|/|_|g'
In your case:
sed -i -e "s|filepath|$filepathvar|g" aimparmstest

SED replace a word inside a bracket [duplicate]

This question already has answers here:
What is the difference between `sed -i -e` and `sed -ie`?
(2 answers)
Closed 2 years ago.
I need to change some words in bulk, but because of the brackets inside it, I think I do something wrong.
Line that needs to be changed
echo "CMD_PLUGINS_ADMIN/admin/index.html";
I need to change it to this:
echo "CMD_PLUGINS_ADMIN/reseller/index.html";
I tried it with: sed -ie 's/admin/reseller/' *
But does not change anything, I hope someone knows the right command for it.
$ echo '"CMD_PLUGINS_ADMIN/admin/index.html";' | sed 's/\/admin\//\/reseller\//g'
"CMD_PLUGINS_ADMIN/reseller/index.html";
your input has slash and you are using slash as sed seperator
Either escape the slashes in input by preceeding them with backslash:
echo '"CMD_PLUGINS_ADMIN/admin/index.html";' | sed 's/\/admin\//\/reseller\//g'
"CMD_PLUGINS_ADMIN/reseller/index.html";
OR change seperator to any other like pipe:
echo '"CMD_PLUGINS_ADMIN/admin/index.html";' | sed 's|admin|reseller|g'
"CMD_PLUGINS_ADMIN/reseller/index.html";

How to use sed or awk or something similar to replace every odd occurrence of character? [duplicate]

This question already has answers here:
Replace every n'th occurrence in huge line in a loop
(4 answers)
Closed 4 years ago.
I have the following string:
"1,0,2,0,3,0,4,0,5,0,6,0,13,05,24233,55".
How to use awk, or sed to get
"1.0,2.0,3.0,4.0,5.0,6.0,13.05,24233.55"?
I tried to use
sed 's/,/./g' <<< "1,0,2,0,3,0,4,0,5,0,6,0,13,05,24233,55"
1.0.2.0.3.0.4.0.5.0.6.0.13.05.24233.55
and also
sed 's/,/./2' <<< "1,0,2,0,3,0,4,0,5,0,6,0,13,05,24233,55"
1,0.2,0,3,0,4,0,5,0,6,0,13,05,24233,55
Which replaced the second item only. I need every odd occurrence changed.
For future, what would be the code the replace every odd occurrence of, by . ?
Thanks for your help
With any sed that supports EREs via -E, e.g. GNU sed and OSX/BSD sed:
$ echo "1,0,2,0,3,0,4,0,5,0,6,0,13,05,24233,55" | sed -E 's/,([^,]+(,|$))/.\1/g'
1.0,2.0,3.0,4.0,5.0,6.0,13.05,24233.55
The above was inspired by #PesaThe's comment to my original answer.
try this:
for the end:
sed 's/[,]$/?/' YourFile
putting the , between [] allow you to remove most of the regex behavior taking litteral value (not for some char like ^ that need to be manage another way
putting the $ is telling to refere to end of string
the g in your test mean change every occurence, you only wanted 1 and at the end
for the internal:
sed -e 's/,/./1;p' \
-e ':a' \
-e 's/^\(\([^.]*[.][^,]*,\)*\)\([^,]*\),\([^,]*\)/\1\3.\4/
/[^,]*,[^,.]*,/ ta' YourFile
you need a loop and a special test due to alternance existing

how to use sed command properly to replace values containing / delimiter [duplicate]

This question already has answers here:
Using different delimiters in sed commands and range addresses
(3 answers)
Closed 5 years ago.
File: abc.properties
tomcat.home=/opt/tomcat
Set to /usr/local/tomcat. Following cmd is working.
sed -i "/tomcat.home=/ s/=.*/="usr\\/local\\/tomcat"/" abc.properties
Set to $WORKSPACE/tomcat. Following cmd is NOT working since value of the $WORKSPACE is having / delimeters.
sed -i "/tomcat.home=/ s/=.*/="$WORKSPACE\\/tomcat"/" abc.properties
Anyone has an idea how to success above cmd.
Thank you and appreciate your support...
Sed lets you use any character you want as the delimiter. Whatever follows the s is used as the separator:
sed -Ee 's/foo/bar/'
sed -Ee 's|foo|bar|'
sed -Ee 's#foo#bar#'
^- All of those are equivalent.
The other option is to escape all your / as \/, but that gets nightmarish fast. Prefer to just pick a separator character that doesn't collide with characters you're trying to use for something else.

Cannot redirect stdout to file specified by full path [duplicate]

This question already has answers here:
why sed replace + redirection deletes my file?
(3 answers)
Closed 7 years ago.
Let
CONFIG_FILE=${WWW_DIR}/${WORDPRESS_TEST_DIR}/wp-config.php
This doesn't work:
sed "${SED_ARG}" ${CONFIG_FILE} >| ${CONFIG_FILE}
(all I get is an empty file). It does not work either when I replace the variables with the actual path strings, nor when I escape the paths with ".
This does work:
sed "${SED_ARG}" ${CONFIG_FILE} >| wp-config.php
mv wp-config.php ${CONFIG_FILE}
so I would assume the sed call works just fine.
Strangely, this does work too:
echo TEST >| ${CONFIG_FILE}
so the sed part might be the problem after all. I am clueless. Any ideas?
The redirection opens the file for writing (not appending), which makes it a new empty file, before the sed command is executed.
You can use the -i flag of sed, to do an in place substitution:
sed -I "${SED_ARG}" "${CONFIG_FILE}"
I also put quotes around ${CONFIG_FILE} to avoid unexpected behavior if it contains any special characters.

Resources