home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.unix.questions:15868 comp.unix.shell:5477
- Path: sparky!uunet!mcsun!sunic!ugle.unit.no!flipper.pvv.unit.no!alkymi.unit.no!arnej
- From: arnej@alkymi.unit.no (Arne Henrik Juul)
- Newsgroups: comp.unix.questions,comp.unix.shell
- Subject: Re: Need help understanding sed
- Date: 23 Jan 93 01:57:25
- Organization: Norwegian Institute of Technology
- Lines: 132
- Message-ID: <ARNEJ.93Jan23015725@ild.alkymi.unit.no>
- References: <1993Jan22.140947@is.morgan.com> <1993Jan22.210855.29212@infolog.se>
- NNTP-Posting-Host: ild.alkymi.unit.no
- In-reply-to: mich@lin.infolog.se's message of Fri, 22 Jan 1993 21:08:55 GMT
-
- In article <1993Jan22.210855.29212@infolog.se>
- mich@lin.infolog.se (Thomas Michanek) writes:
-
- > From: mich@lin.infolog.se (Thomas Michanek)
-
- > I've started to use 'sed' a lot, not only for simple 's/.../.../'
- > substitutions, but I have trouble understanding the man page for sed
- > when trying to using more complex commands. Could someone help me
- > with the following issues:
-
- I'll try to help you a bit, but you also need to read the man page
- more intensely. Some things are best explained by example, though.
-
- > 1. The man page sais:
-
- Some commands use a hold space to save all or part of the
- pattern space for subsequent retrieval.
-
- > However, I can't find _which_ commands do that and how. I've tried
- > using the g, G, h, H, x commands, but sed produces no output.
-
- well, let's look at 'g' and 'h': g copies hold space into pattern
- space, h is vice versa. So
- $ sed '/a/h;/b/g'
- Will `remember' lines containing the letter "a", and replace lines
- containing "b" with the last such `remembered' line.
-
- input output comment
- groo groo
- b line hold space initially empty
- foo foo
- alf alf remember this
- blue alf and copy it in
- glue glue
- blue too alf and copy it in again
- new a line new a line remember
- newer a line newer a line remember
- b line newer a line copy hold space in
- both a and b both a and b remember, then copy
-
-
- > 2. "\n" in a context address is supposed to match a NEWLINE in the
- > pattern space. But doesn't sed read one line at a time into the
- > pattern space, each line separated by NEWLINE?
-
- Yes, you can't use this without using N, which does:
- (2)N Append the next line of input to the pattern
- space with an embedded newline. (The current
- line number changes.)
-
-
- > I want to look for files containing the pattern "A" in one line
- > and the pattern "B" in the next line. The following doesn't work:
- >
- > sed '/A\nB/p'
- >
- > How can you do such a 'multi-line grep'?
-
- $ sed -n 'N;/A.*\n.*B/p'
- will take two and two lines, and check if they together contain the regexp.
- So with input
- hey
- you
- blArg
- foo-BAR
- and
- Alpha
- Beta
- too!
- it will 'grep' out just
- blArg
- foo-Bar
- not the 'Alpha Beta' two-liner because of odd-even considerations. However
- $ sed -n 'N;/A.*\n.*B/p;D'
- will find both, because it doesn't discard *all* of pattern space, just
- the first of the two lines we have got. The normal cycle is:
- In normal operation sed cyclically copies a line of input
- into a pattern space (unless there is something left after a
- D command), sequentially applies all commands with addresses
- matching that pattern space until reaching the end of the
- script, copies the pattern space to the standard output
- (except under -n), and finally, deletes the pattern space.
- It's all in the man page, but it isn't easy :-)
-
- > 3. What's the difference between the commands n and p? The man page sais
- > n copies the pattern space to stdout, but it has never worked for me.
-
- with the -n option, it will *not* copy the pattern space to stdout.
- I think this is just a bug in the man page. But consider
- $ sed '/^ok:/n;s/^/ok:/'
- which adds "ok:" to all lines which does not already have it.
-
- > 4. What's the syntax for the { } command grouping? No matter how I try
- > I get "Extra text at end of command" or "Unrecognized command".
- >
- > Isn't sed '/A/{=;p}' supposed to print the line number and the pattern
- > on stdout? I've tried quoting, backslashing, spaces, no semicolon etc.
-
- It's a bit more baroque than that. '{' is actually a *command*, and you
- would write in a sed script
- /A/{
- =
- p
- }
-
- or in bourne/korn/etc. shell
- $ sed -n '/A/{
- =
- p
- }'
-
- But you can say
- $ sed -n '/A/{;=;p;}'
- which probably does what you want.
-
- > BTW, I'm using C shell on SunOS4.1.1 and "sed0.c 1.15 89/03/28 SMI".
-
- For some things, like commands with embedded newlines, bourne-derived
- shells are much better (for interactive use) than c shell. I personally
- use and recommend GNU's Bourne Again SHell, or at least you should get
- tcsh.
-
- All of my examples above were tested with GNU sed 1.13, some also with
- Sun's /usr/bin/sed, but they should work on most sed variants.
-
- > Your aid is urgent and welcome!!!
-
- Hope this post aided you (and maybe others). I take no responsibility
- for typos :-)
-
- --
- Arne H. Juul -- arnej@lise.unit.no -- University of Trondheim, Norway
-