sed: not interpreting escape characters in variable correctly - bash

I am trying to replace a line in a file with the value of a variable (the variable contains a windows path). Although the variable prints correctly to STDOUT, when used in sed to replace the line of interest, the backslashes disappear.
Any idea how to remedy this? Other ideas welcome.
CODE:
WINPATH="\\\\hd-place\\stor1\\fold1\\archive\\$VAR1.$Var2\\Viewer"
print this to screen (as it should): \\hd-place\stor1\fold1\archive\$VAR1.$Var2\Viewer
The SED command I'm using is: cat file.xml | sed "3 c\
<\RunFolder>$WINPATH</RunFolder>" (please excuse the slashes inside the XML tags)
This outputs this:
\hd-placestor1fold1archive$VAR1.$Var2Viewer
Where as I want this:
\\hd-place\stor1\fold1\archive\$VAR1.$Var2\Viewer

You need one additional layer of escapes for the backslashes, as sed also interprets them after the variable has been expanded.

Related

replace entire line in file with new line given arguments line number and replacement string with special characters

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.

Bash remove every occurrence after first in string

I'm trying to remove everything after a specific_string in a path string in Bash. I've tried using sed to no avail so far.
variable="specific_string"
input_string="/path/to/some/specific_string/specific_string.something/specific_string.something-else"
output=$(sed 's/$variable//' $input_string)
Output should be "/path/to/some/specific_string/"
Would be better if I didn't have to use commands such as sed!
The Problems
There are many problems
Variables are not evaluated inside single quotes. 's/$variable//' will be treated as a literal string, which does not contain specific_string
sed can modify text from files or STDIN, but not text given via parameters. With sed 's/...//' $input_string the /path/to/some/specific_string/.../file is opened and its content is read, instead of the path itself.
s/string// deletes only string, not the words afterwards.
Also remember to double quote your variables. cmd $variable is dangerous if the variable contains spaces. cmd "$variable" is safe.
Sed Solution
output="$(sed "s/$variable.*/$variable/" <<< "$input_string")"
GNU Grep Solution
output="$(grep -Po "^.*?$variable" <<< "$input_string")"
Pure Bash Solution
output="${input_string%%$variable*}$variable"
If you want to remove everything after "specific_string" it will remove the "/" also as it does with the following example:
output=$(echo $input_string|sed "s/${variable}.*$/${variable}/")
try with simple sed:
variable="specific_string"
input_string="/path/to/some/specific_string/specific_string.something/specific_string.something-else"
output=$(echo "$input_string" | sed "s/\(.*$variable\/\).*/\1/")
Output of variable output will be as follows.
echo $output
/path/to/some/specific_string/

Replace in a file with variable containing underscore

File Content(file.txt):
table=$table_name
data=$data_name
Shell Script:
name=kush_123
cat file.txt | grep 'table' | sed "s\table_name\$name\g"
Expected output:
table=$kush_123
This gives error
unterminated s command
if the name variable has _ in it.
If you really want to use a backslash as a delimiter, it needs to be escaped itself so that the double-quoted string preserves it before passing to sed:
sed "s\\table_name\\$name\\g"
Otherwise, sed receives the string stable_name$nameg as its script. (\t, \$, and \g expand to t, $, and g, respectively). In this case, the letter t (as it immediately follows the s) is used as the delimiter, and the error results because there aren't enough ts in the result to provide a complete command.
Of course, if you try this, sed should complain that a backslash cannot be used as the delimiter for the s command. Use a different character:
sed "s/table_name/$name/g"
In general, building such scripts dynamically is fragile, because it assumes you know the value of $name doesn't contain your chosen delimiter.
On more investigation i found out the variable name has trailing spaces as the variable value was passed from python code. I trimmed extra spaces and it worked. Thanks :)

Passing sed a shell-script variable which contains spaces

Ignore the .bat extensions, just a habit from the old dos batch file days.
I have 2 simple shell scripts. I want to pass a filename with spaces (some file with spaces.ext) from little.bat to big.bat, as you can see below. It won't let me put the filename in single or double quotes.
First one called little.bat:
./big.bat some file with spaces.ext
Second one called big.bat:
cat template.iss | sed
"s/replace123/$1/g" | sed
"s/replace456/$1/g" > $1.iss
Escape spaces with another sed command.
you can fine details about the idea here:
Escape a string for a sed replace pattern
You can escape each space with a backslash:
some\ file\ with\ spaces.ext
That way, each space is passed on quoted, and the shell won't parse the space to mean "this is the end of one argument and the start of another".

Sed not working inside bash script

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?

Resources