sed - insert a string with backslash at a specific line number - regex

I have a file which contains multiple latex equations like this :
...
\begin{equation}
\beq{x}=x^{1}\beq{e_{1}}+x^{2}\beq{e_{2}}+x^{3}\beq{e_{3}}
\end{equation}
...
\begin{equation}
\beq{y}=y^{1}\beq{e_{1}}+y^{2}\beq{e_{2}}+y^{3}\beq{e_{3}}
\end{equation}
...
I want to insert just before the "\end{equation}" the string "\tag{number}" where I can successfully get number variable.
To insert this string at the line identified by "$(($line)-1)", I do :
gsed -i "$(($line)-1)i \tag{$number}" file
But I get only :
...
\begin{equation}
\beq{x}=x^{1}\beq{e_{1}}+x^{2}\beq{e_{2}}+x^{3}\beq{e_{3}}
tag{1}
\end{equation}
...
\begin{equation}
\beq{y}=y^{1}\beq{e_{1}}+y^{2}\beq{e_{2}}+y^{3}\beq{e_{3}}
tag{2}
\end{equation}
...
As you can see, I can't print the backslash character at the beginning of "\tag" string
I tried with :
gsed -i "$(($line)-1)i '\'tag{$number}" file
or
gsed -i "$(($line)-1)i \\tag{$number}" file
but no good results,
if someone could see what's wrong ...
Thanks
PS: I am on MacOS X, that's why I used gsed

You need five slashes:
gsed -i "$(($line)-1)i \\\\\tag{$number}" file
Let me explain starting with a single quoted command:
gsed -i '1i \\\test'
You would need three slashes in that case:
The first one delimits the i command with the text to be inserted, the second one escapes the slash itself because otherwise it would get expanded as \t. The third, now escaped, slash, will get inserted as literal \ at the start of the new line.
If we additionally using double quotes to enclose the command,
gsed -i "1i\\\\\test"
the string will get additionally subject of parsing by the shell. Both escaping slashes from the single quoted command, would therefore need to get escaped as well. This makes 5 slashes.
So far so good. But since you are interpolating shell variables into the command, you need to make sure that slashes in them would get escaped as well.

Related

How to find and replace text within ".." using bash script

I want to replace this line #discovery.seed_hosts: ["host1","host2"] with discovery.seed_hosts: ["${extraNode1}","${extraNode2}","${masterIP}"]. Need to remove the # and replace the host1 and host2 as per the given argument also need to add another value (3rd value) into the array as well.
sudo sed -i "/#discovery.seed_hosts: ["host1","host2"]/s/#discovery.seed_hosts: ["host1","host2"]/discovery.seed_hosts: ["${extraNode1}","${extraNode2}","${masterIP}"]/" check.yml
I tried the above command to do this but it is giving error because of the ["host1","host2"] in the command.
sed: -e expression #1, char 49: Invalid range end - Error received
You need to use the s (substitute) command, and escape ., in addition to [. Like this:
sudo sed -i 's/#\(discovery\.seed_hosts: \["\)host1","host2"]/\1${extraNode1}","${extraNode2}","${masterIP}"]/' check.yml
If you don't scape the ., the sed command will match any character where the . is, like #discovery7seed_hosts: ["host1","host2"].
The sed command is pretty straight forward. I just added parentheses around the part of the match that I wanted to reuse in the substitution which creates a group. The \1 is replace with "group 1", the contents of what's in between the parentheses, which must be escaped too.
EDIT: The ", double quotes, don't need to be escaped because the sed command is in single quotes: 's/.../.../'. Also, the ], closing square bracket, doesn't need to be escaped as long as its corresponding [, opening square bracket, has been escaped. Finally, both parentheses ( and ) need to be escaped to create the group. (END OF EDIT)
Test:
$ cat check.yml
This is a test
Another line
#discovery.seed_hosts: ["host1","host2"]
#discovery7seed_hosts: ["host1","host2"]
OK. Good bye?
$ sed 's/#\(discovery\.seed_hosts: \["\)host1","host2"]/\1${extraNode1}","${extraNode2}","${masterIP}"]/' check.yml
This is a test
Another line
discovery.seed_hosts: ["${extraNode1}","${extraNode2}","${masterIP}"]
#discovery7seed_hosts: ["host1","host2"]
OK. Good bye?
$
You'll need to escape [s and "s with backslashes as:
sudo sed -i "/#discovery.seed_hosts: \[\"host1\",\"host2\"]/s/#discovery.seed_hosts: \[\"host1\",\"host2\"]/discovery.seed_hosts: [\""${extraNode1}\"",\""${extraNode2}\"",\""${masterIP}\""]/" check.yml

sed: Replace lines matching a pattern that contains forward slashes?

I know this question has been asked before, I just can't seem to get the correct syntax for my sed command.
I need to replace OPP/com.user.opp.orchest.po.services.stub-npo/npo-stub with OPP/com.user.opp.orchest.po.services.stub-ica/npo-ica
A snippet of the file I am replacing it is the following:
config.xml
<compareType>PLAIN</compareType>
<pattern>
OPP/com.user.opp.orchest.po.services.stub-npo/npo-stub
</pattern>
<branches>
<com.sonyuser.hudson.plugins.gerrit.trigger.hudsontrigger.data.Branch>
<compareType>ANT</compareType>
<pattern>master</pattern>
</com.sonyuser.hudson.plugins.gerrit.trigger.hudsontrigger.data.Branch>
</branches>
${REPO_MIRROR}/OPP/com.user.opp.orchest.po.services.stub-npo/npo-stub
I have tried the following,
sed -i '/^\/OPP/\com.user.opp.orchest.po.services.stub-npo/\npo-stub\/OPP/\com.user.opp.orchest.po.services.stub-ica/\npo-ica/g' config.xml
In your command, you are missing s for substitution and have wrongly escaped \ character. Also as you replied to my comment, that you want to replace it from anywhere in the file, you don't have to use ^ character in your regex. And dot . in regex means any character so they need to be escaped too.
You can use this command,
sed -i 's/OPP\/com\.user\.opp\.orchest\.po\.services\.stub-npo\/npo-stub/OPP\/com.user.opp.orchest.po.services.stub-ica\/npo-ica/g' yourfilename
You need to specify s command and replace the /\ with \/. There are some other typos here as well (\/ at the start is not necessary). Also, escape dots to match literal dots. A good idea is to use some other delimiter here instead of /, e.g. ,, because you have / chars in the regex and replacement parts.
You may use
sed -i 's,^OPP/com\.user\.opp\.orchest\.po\.services\.stub-npo/npo-stub,OPP/com.user.opp.orchest.po.services.stub-ica/npo-ica,' file
See the online demo

I need to use sed to comment out two lines in a text file

I am running a custom kernel build and have created a custom config file in a bash script, now I need to comment out two lines in Kbuild in order to prevent the bc compiler from running. The lines are...
$(obj)/$(timeconst-file): kernel/time/timeconst.bc FORCE
$(call filechk,gentimeconst)
Using Expresso, I have a regex that matches the first line...
^\$\(obj\)\/\$\(timeconst-file\): kernel\/time\/timeconst\.bc FORCE
Regex Match
But can't get sed to actually insert a # in front of the line.
Any help would be much appreciated.
sed -i "/<Something that matches the lines to be replaced>/s/^#*/#/g"
This uses a regex to select lines you want to comment/<something>/, then substitutes /s/ the start of the string ^(plus any #*s already there, with #. So you can comment lines that are already commented no problem. the /g means continue after you found your first match, so you can do mass commenting.
I have a bash script that I can mass comment using the above as:
sed -i.bkp "/$1/s/^#\+\s*//g" $2
i.bkp makes a backup of the file named .bkp
Script is called ./comment.sh <match> <filename>
The match does not have to match the entire line, just enough to make it only hit lines you want.
You can use following sed for replacement:
sed 's,^\($(obj)/$(timeconst-file): kernel/time/timeconst.bc FORCE\),#\1,'
You don't need to escape ( ) or $, as in sed without -r it is treated as literal, for grouping \( \) is used.

search and replace substring in string in bash

I have the following task:
I have to replace several links, but only the links which ends with .do
Important: the files have also other links within, but they should stay untouched.
<li>Einstellungen verwalten</li>
to
<li>Einstellungen verwalten</li>
So I have to search for links with .do, take the part before and remember it for example as $a , replace the whole link with
<s:url action=' '/>
and past $a between the quotes.
I thought about sed, but sed as I know does only search a whole string and replace it complete.
I also tried bash Parameter Expansions in combination with sed but got severel problems with the quotes and the variables.
cat ./src/main/webapp/include/stoBox2.jsp | grep -e '<a href=".*\.do">' | while read a;
do
b=${a#*href=\"};
c=${b%.do*};
sed -i 's/href=\"$a.do\"/href=\"<s:url action=\'$a\'/>\"/g' ./src/main/webapp/include/stoBox2.jsp;
done;
any ideas ?
Thanks a lot.
sed -i sed 's#href="\(.*\)\.do"#href="<s:url action='"'\1'"'/>"#g' ./src/main/webapp/include/stoBox2.jsp
Use patterns with parentheses to get the link without .do, and here single and double quotes separate the sed command with 3 parts (but in fact join with one command) to escape the quotes in your text.
's#href="\(.*\)\.do"#href="<s:url action='
"'\1'"
'/>"#g'
parameters -i is used for modify your file derectly. If you don't want to do this just remove it. and save results to a tmp file with > tmp.
Try this one:
sed -i "s%\(href=\"\)\([^\"]\+\)\.do%\1<s:url action='\2'/>%g" \
./src/main/webapp/include/stoBox2.jsp;
You can capture patterns with parenthesis (\(,\)) and use it in the replacement pattern.
Here I catch a string without any " but preceding .do (\([^\"]\+\)\.do), and insert it without the .do suffix (\2).
There is a / in the second pattern, so I used %s to delimit expressions instead of traditional /.

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