How to find a line in .css file and then changing the correlated config between the following brackets - sed

Let me start off by saying I'm just starting to dabble in sed, awk and regex.
Here's what I need help with.
On ubuntu, in /etc/alternative/gdm3.css I have this config section:
.login-dialog-banner {
color: #d6d6d1; }
I need it to be
.login-dialog-banner{
color: rgba(255,255,255,1);
font-size: 14;
text-align: center;}
I am lost on how to first find .login-dialog-banner and then change the data in the follow on { data }

Would you try the following:
sed '
/\.login-dialog-banner[[:blank:]]*{/{ ;# if the specified 1st line is found
$!{ n ;# and the current line is not the last line, then print it and read the next line
s/.*color:.*/color: rgba(255,255,255,1);\
font-size: 14;\
text-align: center;}/ ;# if the next line contains "color:"
;# then replace the line with the specified lines
}
}' /etc/alternative/gdm3.css

Can you try below sed as per your requirement stated in the question:
sed '/^\.login-dialog-banner {/{N;s/color: #d6d6d1; }/color: rgba(255,255,255,1)\;\nfont-size: 14\;\ntext-align: center\;}/}' /etc/alternative/gdm3.css
I'm searching for the line starting with string .login-dialog-banner { and then substituting the second line : color: #d6d6d1; } with your next required data.
If the above command is working for you, you can include -i option for edit the file inplace.
sed -i '/^\.login-dialog-banner {/{N;s/color: #d6d6d1; }/color: rgba(255,255,255,1)\;\nfont-size: 14\;\ntext-align: center\;}/}' /etc/alternative/gdm3.css
From man sed:
i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if SUFFIX supplied)

Related

sed over multiple lines to replace a single number

Im new to sed and found some instructiones to that kind of probmen, but none of them worked for me.
I have a file called var.tf with that entry:
variable "nb_instances" {
description = "Specify the number of vm instances"
default = "3"
}
and want to replace the "3" with "4".
I tried to create that bash skript:
#!/usr/bin/env bash
sed 's/variable \"nb_instances\" {
description = \"Specify the number of vm instances\"
default = \"3\"
}/variable \"nb_instances\" {
description = \"Specify the number of vm instances\"
default = \"4\"
}/g' var.tf
but it doesn´t work and gives an error:
sed: 1: "s/variable \"nb_instanc ...": unterminated substitute pattern
Can anyone help me with that? I also tried to include \n for the new lines.
This might work for you (GNU sed):
sed '/^variable "nb_instances" {/{:a;n;s/"3"/"4"/;Ta}' file
Focus on the first line beginning variable "nb_instances" { then continue reading/printing lines until the string "3" is replaced by "4".

Sed: How to insert a pattern which includes single ticks?

I'm trying to use sed to replace a specific line within a configuration file:
The pattern for the line I want to replace is:
ALLOWED_HOSTS.*
The text I want to insert is:
'$PublicIP' (Including the single ticks)
But when I run the command:
sed 's/ALLOWED_HOSTS.*/ALLOWED_HOSTS = ['$PublicIP']/g' /root/project/django/mysite/mysite/settings.py
The line is changed to:
ALLOWED_HOSTS = [1.1.1.1]
instead of:
ALLOWED_HOSTS = ['1.1.1.1']
How shall I edit the command to include the single ticks as well?
You could try to escape the single ticks , or better you can reassign the variable including the simple ticks:
PublicIP="'$PublicIP'".
By the way even this sed without redifining var, works ok in my case:
$ a="3.3.3.3"
$ echo "ALLOWED_HOSTS = [2.2.2.2]" |sed 's/2.2.2.2/'"'$a'"'/g'
ALLOWED_HOSTS = ['3.3.3.3']
Even this works ok:
$ echo "ALLOWED_HOSTS = [2.2.2.2]" |sed "s/2.2.2.2/'$a'/g"
ALLOWED_HOSTS = ['3.3.3.3']

linux sed how to wrap a multiline search pattern with text

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'

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.

Insert double quotes multiple times into string

I have inherited a flat html file with a few hundred lines similar to this:
<blink>
<td class="pagetxt bordercolor="#666666 width="203 colspan="3 height="20>
</blink>
So far I have not been able to work out a sed way of inserting the closing double quotes for each element. Probably needs something other than sed to do this. Can anyone suggest an easy way to do this?
Thanks
sed -i 's/"\([^" >]\+\)\( \|>\)/"\1"\2/g' file.html
Explanation:
" - leading double quote
\([^" >]\+\) - non-quote-or-space-or-'>' chars, grouped (into group 1)
\( \|>\) - terminating space or '>', grouped (into group 2)
We replace it with '"<group1>"<group2>'.
One solution that pops out at me is to parse through each line of the file looking for the quote. When it finds one, activate a flag to keep track of being inside a quoted area, then continue parsing the line until it hits the first space or > it comes to and inserts an additional " just before it. Flip the flag off, then continue through the string looking for the next quote. Probably not a perfect solution, but a start perhaps.
If all lines share the same structure, you could use a simple texteditor to globally replace
' bordercolor'
with
'" bordercolor'
(without single-quotes). This is then independend from the field values and works similarly for the other fields. You still have to do some manual work, but if it's just one big file, I'd bite the bullet this time and not waste probably more time working out a sed-solution.
This should do if your file is simple - it won't work if you have whitespace which should be inside the quotes - in that case, a more complex code will be needed, but can be done along the same lines.
#!usr/bin/env python
#change the "utf-8" bellow to your files encoding
data = open("<myfile.html>").read().decode("utf-8")
new_data = []
inside_tag = False
inside_quotes = False
for char in data:
if char == "<":
inside_tag = True
if char == '"':
inside_quotes = True
if inside_tag and (char.isspace() or char==">") and inside_quotes:
new_data.append('"')
inside_quotes = False
if char == ">":
inside_tag = False
new_data.append(char)
outputfile = open("<mynewfile.html>", "wt")
outputfile.write("".join(new_data).encode("utf-8"))
outputfile.close()
with bash
for file in *
do
flag=0
while read -r line
do
case "$line" in
*"<blink>"*)
flag=1
;;
esac
if [ "$flag" -eq 1 ];then
case "$line" in
*class=\"pagetxt*">" )
line="${line%>}\">"
flag=0
;;
esac
fi
echo "${line}"
done <"file" > temp
mv temp "$file"
done
Regular expressions are your friend:
Find: (="[^" >]+)([ >])
Replace: \1"\2
After you've done that, make sure to run this one too:
Find: </?blink>
Replace: \n
(This won't fix more than one class on an element, like <element class="class1 class2 id="jimmy">)