How to substitute a phrase with dollar mark with sed - regex

For substitution of a phrase I simply use:
sed -i "s:phrase_to_be_matched*:phrase_to_be_replaced_with:g" file_name
This works fine, until i have the following problem:
I have a line in a file,
#$ModLoad imudp
What i want,
$ModLoad imudp
I am currently running this,
sed -i "s:.*$ModLoad imudp.*:$ModLoad imudp:g" file
But i am getting:
imudp
I know, this is happening because, $ModLoad imudp is considered as a variable, and as it doesn't exist I am getting this output.
I have tried with "$ModLoad imudp" too, but got the same result.
I can't simply remove the# because, i have other commented line in my file.
How to resolve this?

Try using single quotes '' instead of double quotes.
sed -i 's:.*$ModLoad imudp.*:$ModLoad imudp:g' file
This prevents special meaning of $ for variable expansion.
Edit: (as per #tripleee's comment)
Also escape $ for matching literal dollar sign
sed -i 's:.*\$ModLoad imudp.*:$ModLoad imudp:g' file

Related

Sed error: bad flag in substitute command: 'U'

I'm new in bash script and trying to replace some words in my file using sed. Following is the bash I use in my script:
sed -i '' "s/<pre>.*<\/pre>/<pre>($NEWNAME) $MD5<\/pre>/"~/Desktop/replace.html
And I got error message saying: bad flag in substitute command: 'U'. I use double quote because I need to put variables in.
My environment is Mac.
======================================
1.Turns out I forgot to leave a space between replace string and file name. Which led to the result always showing: bad flag in substitute command: '~'. It works now.
2.The reason is I used MD5=$(md5 path) to create MD5 value which gets the reault of MD5 (path) *****, and the path contains / which breaks the regex. After changing MD5=$(md5 -q path), it will be ok.
Most likely your $NEWNAME variable has a forward slash in it, which is being used as regex delimiter in sed. Try this sed with an alternate delimiter e.g. ~:
sed -i '' "s~<pre>.*</pre>~<pre>($NEWNAME) $MD5</pre>~" ~/Desktop/replace.html

White spaces in sed search string

I want to substitute a String from a file which is:
# - "server1"
My first attempt was something like this:
sed -i 's/#\ -\ "\server1"\.*/ChangedWord/g' file
But I get an error if I try it like this.
So there is to be another way to handle whitespaces, I guess I have to use \s or [[:space:]]. But for some how I am not able to make it work.
I think you are complicating the expression too much. This should be enough:
sed 's/^#[[:space:]]*-[[:space:]]*"server1".*/ChangedWord/' file
It looks for those lines starting with # followed by 0 to n spaces, then "server1" and then anything. In such case, it replaces the line with ChangedWord.
Note I am using [[:space:]] to match the spaces, since it is a more compatible way (thanks Tom Fenech in comments).
Note also there is no need to use g in the sed expression, because the pattern can occur just once per line.
Test
$ cat a
hello
# - "server1"
hello# - "server1"
$ sed 's/^#[[:space:]]*-[[:space:]]*"server1".*/ChangedWord/' a
hello
ChangedWord
hello# - "server1"
The actual fault was the missing escaping from the double quotes:
ssh -i file root#IP sed 's/^#[[:space:]]*-[[:space:]]*\"server1\".*/ChangedWord/' file
That did it for me. Thanks for all your support
rghome is right, you don't need those backslashes in front of spaces as the expression is wrapped in quotes. In fact, they're causing the error: sed is telling you that \<Space> is not a valid option. Just remove them and it should work as expected:
sed -i 's/# - "server1"/ChangedWord/' file

sed replace exact match

I want to change some names in a file using sed. This is how the file looks like:
#! /bin/bash
SAMPLE="sample_name"
FULLSAMPLE="full_sample_name"
...
Now I only want to change sample_name & not full_sample_name using sed
I tried this
sed s/\<sample_name\>/sample_01/g ...
I thought \<> could be used to find an exact match, but when I use this, nothing is changed.
Adding '' helped to only change the sample_name. However there is another problem now: my situation was a bit more complicated than explained above since my sed command is embedded in a loop:
while read SAMPLE
do
name=$SAMPLE
sed -e 's/\<sample_name\>/$SAMPLE/g' /path/coverage.sh > path/new_coverage.sh
done < $1
So sample_name should be changed with the value attached to $SAMPLE. However when running the command sample_name is changed to $SAMPLE and not to the value attached to $SAMPLE.
I believe \< and \> work with gnu sed, you just need to quote the sed command:
sed -i.bak 's/\<sample_name\>/sample_01/g' file
In GNU sed, the following command works:
sed 's/\<sample_name\>/sample_01/' file
The only difference here is that I've enclosed the command in single quotes. Even when it is not necessary to quote a sed command, I see very little disadvantage to doing so (and it helps avoid these kinds of problems).
Another way of achieving what you want more portably is by adding the quotes to the pattern and replacement:
sed 's/"sample_name"/"sample_01"/' script.sh
Alternatively, the syntax you have proposed also works in GNU awk:
awk '{sub(/\<sample_name\>/, "sample_01")}1' file
If you want to use a variable in the replacement string, you will have to use double quotes instead of single, for example:
sed "s/\<sample_name\>/$var/" file
Variables are not expanded within single quotes, which is why you are getting the the name of your variable rather than its contents.
#user1987607
You can do this the following way:
sed s/"sample_name">/sample_01/g
where having "sample_name" in quotes " " matches the exact string value.
/g is for global replacement.
If "sample_name" occurs like this ifsample_name and you want to replace that as well
then you should use the following:
sed s/"sample_name ">/"sample_01 "/g
So that it replaces only the desired word. For example the above syntax will replace word "the" from a text file and not from words like thereby.
If you are interested in replacing only first occurence, then this would work fine
sed s/"sample_name"/sample_01/
Hope it helps

Sed with both " and ' in insert string

I am using sed command in Ubuntu for making shell script.
I have a problem because the string I am inserting has both single and double quotes. Dashes also. This is the expample:
sed -i "16i$('#myTable td:contains("Trunk do SW-BG-26,
GigabitEthernet0/22")').parents("tr").remove();" proba.txt
It should insert
$('#myTable td:contains("Trunk do SW-BG-26, GigabitEthernet0/22")').parents("tr").remove();
in line 16 of the file proba.txt
but instead it inserts
$('#myTable td:contains(
because it exits prematurely . How can resolve this, I cannot find solution here on site bcause I have both quotation signs and there are explanations only for one kind.
2nd try
I set \ in front every double quote except the outermost ones but I still didn't get what I want. Result is:
.parents("tr").remove();
Then I put \ in front of every ' too but the result was an error in script. This is the 4th row:
sed -i "16i$(\'#myTable td:contains(\"QinQ tunnel - SCnet wireless\")\').parents(\"tr\").remove();" proba.txt
This is the error:
4: skripta.sh: Syntax error: "(" unexpected (expecting ")")
Maybe there is easier way to insert line into the file at the exact line if that line has ", ', /?
3rd time is a charm
Inserting many lines last day I came across another problem using sed. I want to insert this text:
$(document).ready( function() {
with command:
sed -i "16i$(document).ready( function() {" proba.txt
and I get as result this text inserted as document is something special or because of the $:
.ready( function() {
Any thoughts about that?
There are two ways around this. The easy way out is to put the script into a file and use that on the command line. For example, sed.script contains:
16i\
$('#myTable td:contains("Trunk do SW-BG-26, GigabitEthernet0/22")').parents("tr").remove();
and you run:
sed -f sed.script ...
If you want to do it without the file, then you have to decide whether to use single quotes or double quotes around your sed -e expression. Using single quotes is usually easier; there are no other special characters to worry about. Each embedded single quote is replaced by '\'':
sed -e '16i\
$('\''#myTable td:contains("Trunk do SW-BG-26, GigabitEthernet0/22")'\'').parents("tr").remove();' ...
If you want to use double quotes, then each embedded double quote needs to be replaced by \", but you also have to escape embedded back quotes `, dollar signs $ and backslashes \:
sed -e "16i\\
\$('#myTable td:contains(\"Trunk do SW-BG-26, GigabitEthernet0/22\")').parents(\"tr\").remove();" ...
(To the point: I forgot to escape the $ before I checked the script with double quotes; I got the script with single quotes right first time.)
Because of all the extra checking, I almost invariably use single quotes, unless I need to get shell variables substituted into the script.
sed -i "6 i\\
\$('#myTable td:contains(\"Trunk do SW-BG-26, GigabitEthernet0/22\")').parents(\"tr\").remove();" proba.txt
escape the double quote, the slash and new line needed after the i instruction and the $ due to double quote shell interpretation

sed: cannot seem to match pattern to line

If I have sed script like this:
35185222p
And run it as:
sed -n -f seddy.sed infile.xml
It correctly prints out the dodgy line of XML I want to fix.
If I change my script to:
35185222s#^.*$#<load address='11b38c56' size='08' />#p
It doesn't make the match (ie no output is made). What have I got wrong?
OK: I think I get this now - unfortunately the corruption in this line in the original file means characters won't match to a . - so how do I fix that?
Further update This is what the line looks like when I cut and paste it:
<load address='11c1�����ze='08' />
Try the sed c command to change the contents of the line:
35185222c\<load address='11b38c56' size='08' />
I frankly don't know why the regex ^.*$ would not match on that line. My guess is that it has something to do with your locale and character encodings, but it seems like it has to be a bug either way.
The real issue appears to be a clash of locales.
Running
LANG=c sed -f seddy.sed input.xml
Fixes the problem. Of course, I could have used the c command instead.
35185222s#[^].*[$]#<load address='11b38c56' size='08' />#p
^ and $ should be escaped or between [ ] at least if not, there meaning (^ = begin, $ = end) is used and there is nothing before a begining nor after a end.
be carrefull also with the ', it depend of your string delimiter from your sed and must mybe are escpaed too