Replace text with sed

A program creates HTML files from a database. There are headings and stuff in between the headings.

There are not a set amount of headings. After each heading the program places the text:

$WHITE*("5")$ 

$WHITE*("20")$ 
$HRULE$ 

I need every occurrence of these 4 lines to be replaced with:

$WHITE*("20")$ 
$HRULE$ 
$WHITE*("10")$ 

I am not fussed what program is used :)

I have tried:

sed 's:\$WHITE\*(\"5\")\$\n\n\$WHITE\*(\"20\")\$\n\$HRULE\$:\$WHITE\*(\"20\")\$\
\$HRULE$\
\$WHITE*("10")$:g'

and various other permutations

Answers


UPDATE #2

From the sed faq, section 4.23.3

If you need to match a static block of text (which may occur any number of times throughout a file), where the contents of the block are known in advance, then this script is easy to use

UPDATE #1

Python?

$ cat input
first line
second line
3rd line
$WHITE*("5")$

$WHITE*("20")$
$HRULE$
some more lines
yet another
$WHITE*("5")$

$WHITE*("20")$
$HRULE$
THE END

the script:

#!/usr/bin/env python

## Use these 3 lines for python version < 2.5
#fd=open('input')
#text=fd.read()
#fd.close()

## Use these 2 lines for python version >= 2.5
with open('input') as fd:
    text=fd.read()

old="""$WHITE*("5")$

$WHITE*("20")$
$HRULE$
"""

new="""$WHITE*("20")$
$HRULE$
$WHITE*("10")$
"""

print text.replace(old,new)

output:

first line
second line
3rd line
$WHITE*("20")$
$HRULE$
$WHITE*("10")$
some more lines
yet another
$WHITE*("20")$
$HRULE$
$WHITE*("10")$
THE END

If that'S your input file, and this is the spec, you can do:

sed -n '3,$p;$a$WHITE*("10")$' INPUTFILE

But I assume that's not the case, so you might want to rephrase your question and/or giving some more detailes.

More specific solution with sed:

 sed '/^\$WHITE\*("5")\$$/,/^$/d;/\$HRULE\$/ a$WHITE*("10")$' INPUTFILE

(Searches for the $WHITE*("5")$ line and deletes it till (including!) the next empty line. Then searches for the next $HRULE$ line and appends an $WHITE*("10")$ line.

awk solution:

 awk '/\$WHITE\*\("5"\)\$/ { getline ; next } 
      /\$WHITE\*\("20"\)\$/ { print ; 
                              getline ; 
                              if ($0 ~ /\$HRULE\$/) { print ; 
                                                      print "$WHITE*(\"10\")$" ;
                                                    }
                              else { print }
                            }
      1 ' INPUTFILE 

This reads the file and prints every line - that's why the 1 is there, except if it finds the $WHITE*("5") pattern it drops it, reads the next line and drops that too. if it finds the $WHITE*("20") prints it. Reads the next line and if its $HRULE$ then prints that and the appended $WHITE*("10") line. Else just prints the line.

HTH


Try something like

 sed -e '${p;};/$WHITE\*("5")\$/,/$HRULE\$/{H;/$HRULE\$/{g;s/$HRULE\$//;s/20/10/;s/5/20/;s/\n/&$HRULE$/2p;s/.*//p;x;d;};d;};' white.txt

Crude, but it should work.


This might work for you:

 sed '/^\$WHITE\*(\"5\")\$/{N;N;N;s/.*\n\n\(\(\$WHITE\*(\"\)20\(\")\$\s*\)\n\$HRULE\$\s*$\)/\1\n\210\3/}' file

Explanation:

Match on first string $WHITE*("5")$, read the next 3 lines and match on remainder. Use grouping and back references to formulate output lines.


Need Your Help

How to create an email with embedded images that is compatible with the most mail clients

mime attachment embedded-resource

We have created a system that allows embedding an image in an outgoing email.

Python tkinter app adding a right click context menu?

python user-interface tkinter contextmenu

I have a python-tkinter gui app that I've been trying to find some way to add in some functionality. I was hoping there would be a way to right-click on an item in the app's listbox area and bring ...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.