linux sed how to wrap a multiline search pattern with text - sed

I have a html file which includes a section as follows:
<div id='webnews'>
... variable stuff ...
</div>
which I want to comment out as follows:
<!--
<div id='webnews'>
... variable stuff ...
</div>
-->
I can find & print the multiline text as follows:
sed '/<div id="webnews"/, /<\/div>/ { p }' filename.html
Experimenting with h, d, x and G, I have been unable work out how to either wrap the hold buffer or the pattern buffer with '<!--' and '-->'.
Would appreciate help with this challenge.

quick and dirty with sed (not the best idea on html unless you are sure of html content/structure)
sed "/<div id='webnews'/, /<\/div>/ {
/<div id='webnews'/ {
h
d
}
H
/<\/div>/ !d
x
s/^/<!--\\
/
s/$/\\
-->/
}" filename.html

This might work for you (GNU sed):
sed -e '/<div id='\''webnews'\''>/,/<\/dev>/!b;/<div id='\''webnews'\''>/i\<!--' -e '/<\/div>/a\-->' file
Or perhaps:
sed $'/<div id=.webnews.>/,/<\/dev>/{/<div id=.webnews.>/i\<!--\n;/<\/div>/a\-->\n}' file

Sed is not the right tool for the job.
Use sift:
sift -m '(.+)(<div id=.webnews.>.*</div>)(.+)' --replace '$1<!-- $2 -->$3'

Related

sed add different lines in different files

I'm trying to find a way to run multiple sed commands that adds lines to the start of different files (on Mac OS).
This works when run from terminal.
sed -i '' '1i\
\\version \"2.19.65\"\
\\language \"english\"\
\\include \"dynamics-defs.ily\"\
altosaxINotes = \\transpose c ef {\
\\relative c {\
' altosaxI.ily
But I want to add slightly different text on a different file:
sed -i '' '1i\
\\version \"2.19.65\"\
\\language \"english\"\
\\include \"dynamics-defs.ily\"\
altosaxIINotes = \\transpose c ef {\
\\relative c {\
' altosaxII.ily
I have about 30 or 40 of these to run, all slightly different. Is it possible to combine them all into one terminal command, or perhaps use Mac's automator, or maybe a better solution?
This might work for you (GNU sed):
# create a function f with one parameter
f(){ cat <<! >tempFile && sed -i '1e cat tempFile' ${1}.ily; }
\\version "2.19.65"
\\language "english"
\\include "dynamics-defs.ily"
${1}Notes = \\transpose c ef {
\\relative c {
!
# call the function
f altosaxI
The function f can then be included in a for-loop or a script.

use sed to change a text report to csv

I have a report looks like this:
par_a
.xx
.yy
par_b
.zz
.tt
I wish to convert this format into csv format as below using sed 1 liner:
par_a,.xx
par_a,.yy
par_b,.zz
par_b,.tt
please help.
With awk:
awk '/^par_/{v=$0;next}/^ /{$0=v","$1;print}' File
Or to make it more generic:
awk '/^[^[:blank:]]/{v=$0;next} /^[[:blank:]]/{$0=v","$1;print}' File
When a line starts with par_, save the content to variable v. Now, when a line starts with space, change the line to content of v followed by , followed by the first field.
Output:
AMD$ awk '/^par_/{v=$0}/^ /{$0=v","$1;print}' File
par_a,.xx
par_a,.yy
par_b,.zz
par_b,.tt
With sed:
sed '/^par_/ { h; d; }; G; s/^[[:space:]]*//; s/\(.*\)\n\(.*\)/\2,\1/' filename
This works as follows:
/^par_/ { # if a new paragraph begins
h # remember it
d # but don't print anything yet
}
# otherwise:
G # fetch the remembered paragraph line to the pattern space
s/^[[:space:]]*// # remove leading whitespace
s/\(.*\)\n\(.*\)/\2,\1/ # rearrange to desired CSV format
Depending on your actual input data, you may want to replace the /^par_/ with, say, /^[^[:space:]]/. It just has to be a pattern that recognizes the beginning line of a paragraph.
Addendum: Shorter version that avoids regex repetition when using the space pattern to recognize paragraphs:
sed -r '/^\s+/! { h; d; }; s///; G; s/(.*)\n(.*)/\2,\1/' filename
Or, if you have to use BSD sed (as comes with Mac OS X):
sed '/^[[:space:]]\{1,\}/! { h; d; }; s///; G; s/\(.*\)\n\(.*\)/\2,\1/' filename
The latter should be portable to all seds, but as you can see, writing portable sed involves some pain.

sed replacement value between to matches

Hi I want to replace a string coming between to symbols by using sed
example: -amystring -bxyz
what to replace mystring with ****
value after -a can be anything like -amystring 123 -bxyz, -amystring 123<newline_char>, -a'mystring 123' -bxyz, -a'mystring 123'<newline_char>
I tried following regex but it does not work in all the cases
sed -re "s#(-w)([^\s\-]+)#\1**** #g"
can anybody help me to solve this issue ?
MyString="YourStringWithoutRegExSpecialCharNotEscaped"
sed "s/-a${MyString} -b/-a**** -b/g"
if you can escape your string for any regex key char like * + . \ / with something like
echo "${MyString}" | sed 's/\[*.\\/+?]/\\&/g' | read -r MyString
before us it in sed.
otherwise, you need to better define the edge pattern

remove all words containing backslash

ive been tring sooooo many different variations to get this right.
i am simply looking to use sed to remove all words beginning with or containing a backslash.
so string
another test \/ \u7896 \n test ha\ppy
would become
another test test
i've tried soo many different options, but it doesnt seem to want to work. Does anybody have an idea how to do this?
and before everyone starts giving me minus 1 for this question, believe me, i have tried to find the answer.
You could use str.split and a list comprehension:
>>> strs = "another test \/ \u7896 \n test ha\ppy"
>>> [x for x in strs.split() if '\\' not in x]
['another', 'test', 'test']
# use str.join to join the list
>>> ' ' .join([x for x in strs.split() if '\\' not in x])
'another test test'
$ echo "another test \/ \u7896 \n test ha\ppy" | sed -r 's/\S*\\\S*//g' | tr -s '[:blank:]'
another test test
This might work for you (GNU sed):
sed 's/\s*\S*\\\S*//g' file
string = "another test \/ \u7896 \n test ha\ppy"
string_no_slashes = " ".join([x for x in string.split() if "\\" not in x])

How to replace text using greedy approach in sed?

I am parsing one file which has some html tag and changing into latex tag.
cat text
<Text>A <strong>ASDFF</strong> is a <em>cerebrovafdfasfscular</em> condifasdftion caufadfsed fasdfby tfdashe l
ocfsdafalised <span style="text-decoration: underline;">ballooning</span> or difdaslation of an arfdatery in thdfe bfdasrai
n. Smadfsall aasdneurysms may dadisplay fdasno ofadsbvious sdfasigns (<span style="text-decoration: underline;"><em><str
ong>asymptomatic</strong></em></span>) bfdasut lfdsaarger afdasneurysms maydas besda asfdsasociated widfth sdsfudd
sed -e 's|<strong>\(.*\)</strong>|\\textbf{\1}|g' test
cat out
<Text>A \textbf{ASDFF</strong> is a <em>cerebrovafdfasfscular</em> condifasdftion caufadfsed fasdfby tfdashe locfsda
falised <span style="text-decoration: underline;">ballooning</span> or difdaslation of an arfdatery in thdfe bfdasrain. Sma
dfsall aasdneurysms may dadisplay fdasno ofadsbvious sdfasigns (<span style="text-decoration: underline;"><em><strong&gt
;asymptomatic}</em></span>) bfdasut lfdsaarger afdasneurysms maydas besda asfdsasociated widfth sdsfudd
Expected outputs should be \textbf{ASDFF} while i observe \textbf{ASDFF .........}. How to get expected result?
Regards
You may want to use perl regex instead.
perl -pe 's|<strong>(.*?)</strong>|\\textbf{\1}|g'
Your problem is similar with non-greedy-regex-matching-in-sed. And next time you may want to simplify your case to point out the real problem. For example, don't just paste the raw html code, use this instead:
fooTEXT1barfooTEXT2bar
Update
If you just want the greedy approach, just ignore this.