Solved

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

Posted on 2007-04-05
Medium Priority
5,103 Views
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
Question by:ibanja
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 4
• 2
• 2
• +1

LVL 84

Expert Comment

ID: 18860010
do you want
sed -n '/ldot/p'
0

Author Comment

ID: 18860341
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

ID: 18867245
try

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

LVL 51

Expert Comment

ID: 18876427
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 LVL 6 Accepted Solution DocGyver earned 2000 total points ID: 18885705 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 ID: 18891369 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

ID: 18891427
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

ID: 18892639
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

ID: 18892758
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

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It is a general practice to get rid of old user profiles on a computer  in a LAN environment. As I have been working with a company in a LAN environment where users move from one place to some other place at times. This will make many user profil…
We are witnesses that everyone is saying that our children shouldn't "play" with a technology because it is dangerous. This article is going to prove that they are wrong.
Learn the basics of if, else, and elif statements in Python 2.7. Use "if" statements to test a specified condition.: The structure of an if statement is as follows: (CODE) Use "else" statements to allow the execution of an alternative, if the …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
###### Suggested Courses
Course of the Month10 days, 12 hours left to enroll