Solved

using sed - how do I delete lines above and below a match?

Posted on 2007-04-05
9
4,682 Views
Last Modified: 2012-08-13
using sed - I need to delete one line above and one line below any line with "ldots" on it.  

In the example below all of the lines with "\backslash" and all the lines with "\end_layout" have to be deleted.   There are other  lines with  "\end_layout" that need to stay so that's why I can't do something like:
sed -e 's/\\end_layout//'

Example:
$ grep -A1 -B1 ldots sampleDoc.lyx
\backslash
ldotsye
\end_layout
--
\backslash
ldotsforeordained
\end_layout
--
\backslash
ldotsAnd
\end_layout
--
\backslash
ldotsfor
\end_layout
--
\backslash
ldotsthat
\end_layout
--
\backslash
ldotsI
\end_layout
--
\backslash
ldotsboth
\end_layout
--
\backslash
ldotsleaving
\end_layout
--
\backslash
ldotsthat
\end_layout
--
\backslash
ldotsas
\end_layout

An explanation of the arguments would be appreciated.  I've been trying to make sense of these sed one-liners to apply to my problem.

# print 1 line of context before and after regexp, with line number
# indicating where the regexp occurred (similar to "grep -A1 -B1")
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h

# print the line immediately before a regexp, but not the line
 # containing the regexp
 sed -n '/regexp/{g;1!p;};h'

 # print the line immediately after a regexp, but not the line
 # containing the regexp
 sed -n '/regexp/{n;p;}'

Thanks,
Frank
0
Comment
Question by:ibanja
  • 4
  • 2
  • 2
  • +1
9 Comments
 
LVL 84

Expert Comment

by:ozo
Comment Utility
do you want
sed -n '/ldot/p'
0
 

Author Comment

by:ibanja
Comment Utility
No, because I need the rest of the file.  I only want to delete the lines above and the lines below a match.

Example: I want to take this:
line one
line two

\backslash
ldotsleaving
\end_layout

last line

and turn it into this:
line one
line two

ldotsleaving

last line

Thanks
0
 
LVL 6

Expert Comment

by:DocGyver
Comment Utility
try

sed -e 'g/ldots/-1,+1d'
0
 
LVL 51

Expert Comment

by:ahoffmann
Comment Utility
I'd use perl or awk instead:
awk '(s==1){s=0;next}{x++}/ldots/{x--;s=1}{a[x]=$0}END{for(x in a){print a[x]}}' yourfile
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 6

Accepted Solution

by:
DocGyver earned 500 total points
Comment Utility
Sorry I missed the fact that you want the line inbetween to stay.  Sounds like you are cleaning out formatting tags from around matching lines.  Mine would take the "ldots" line too.  Here's the correction and, as you asked, an explanation also.

This is a bit of an extreme example for sed (I would use either ed or ex myself) since they are not stream oriented and can back track in the file.  That's why my earlier example didn't work.  I was thinking in 'ed".  All the same here is your result with an explanation:

sed -n -e '1h' -e '1!H' -e '/ldots/{p;n;n;h;d}' -e 1b -e 'x;P' < yourfile

-n                          "do not print unless I tell you to"
-e '1h'                    "if this is the first line initialize the hold buffer with the line
-e '1!H'                   "if this is not the first line then ADD the line to the hold buffer
-e '/ldots/{...}'         "if the current line has /ldots/ in it then p-print, get the next line, another next line
                               reinitialize the hold buffer, and delete the pattern buffer"  The delete is so we cycle
                               to the top
-e 1b                       "if we are on the first line then jump to the end"  need this to handle the special case
                                 of the first line containing your search string (ldots)
-e 'x;P'                   "otherwise exchange the current line with the hold buffer and 1 line of the hold buffer

Only reason this works is you only want to get a single line above and below.  If you wanted to do more lines you would have to resort to using 'ed' or some other scripting language.

Doc..
0
 

Author Comment

by:ibanja
Comment Utility
ahoffmann,

thanks for the input but I could not get this to work.  It was scrambling the document somehow.  I created a short sedTest doc by running "grep -A1 -B1 ldots sampleDoc.lyx > sedTest" which produces the exact same output as in my original question - dumped to the file named sedTest. I then ran line that you gave and got the following:

$ awk '(s==1){s=0;next}{x++}/ldots/{x--;s=1}{a[x]=$0}END{for(x in a){print a[x]}}' sedTest
ldotsthat
--
--
ldotsAnd
ldotsas
--
ldotsfor
--
ldotsthat
--
ldotsI
--
ldotsboth
--
ldotsye
ldotsleaving
--
--
ldotsforeordained
0
 

Author Comment

by:ibanja
Comment Utility
DocGyver,

That is perfect.  It works and thanks so much for the explanation.  That clearifies a few questions I have had about how to use some of the options in sed, especially the h and the n.  I could never get them to work and didn't have any good examples to compare to.

Much appreciated,
Frank
0
 
LVL 51

Expert Comment

by:ahoffmann
Comment Utility
you got a solution, perfect.
According my suggestion, the result you posted is exactly what it should do as I understand it from your description.
0
 

Author Comment

by:ibanja
Comment Utility
ahoffmann,

"According my suggestion, the result you posted is exactly what it should do as I understand it from your description."

Sorry, I might have to be more clear.  Thanks though.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Introduction This tutorial will give you a fast look what you can do with WhizBase. I expect you already know how to work with HTML at least, and that you understand the basics of the internet and how the internet works. WhizBase is a server-s…
This tutorial will discuss fancy secure registration forms, with AJAX technology support. In this article I assume you already know HTML and some JS. I will write the code using WhizBase Server Pages, so you need to know some basics in WBSP (you mig…
Learn the basics of lists in Python. Lists, as their name suggests, are a means for ordering and storing values. : Lists are declared using brackets; for example: t = [1, 2, 3]: Lists may contain a mix of data types; for example: t = ['string', 1, T…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now