threads / discuss / 9372

Help a sed noob

Subject: Help a sed noob

## tl;dr

11 messages between Aug 3, 2007 and Aug 4, 2007.

replies: 10people: 7as markdown or json

Nguyen Thai Ngoc Duy· Aug 3, 2007, 23:22 UTC · lore
Hi,

There is a construct like this in git-parse-remote.sh which makes busybox ash unhappy:

                sed -ne '/^URL: */{
                        s///p
                        q
                }' "$GIT_DIR/remotes/$1"

It complains about "no previous regexp" while gnu sed is ok. Can anyone explain to me what does "s///p" do? GNU Sed info page says nothing about empty regexp. If I replace it with "s/\(.*\)/\1/p" then I get "URL: " along with the remote path.

By the way, can we use another construct instead? It would be less work for me ;-)

-- 
Duy
Junio C Hamano· Aug 3, 2007, 23:38 UTC · re: Nguyen Thai Ngoc Duy · lore

Re: Help a sed noob

"Nguyen Thai Ngoc Duy" <pclouds@gmail.com> writes:
Show 12 quoted lines
> There is a construct like this in git-parse-remote.sh which makes
> busybox ash unhappy:
>
>                 sed -ne '/^URL: */{
>                         s///p
>                         q
>                 }' "$GIT_DIR/remotes/$1"
>
> It complains about "no previous regexp" while gnu sed is ok. Can
> anyone explain to me what does "s///p" do? GNU Sed info page says
> nothing about empty regexp. If I replace it with "s/\(.*\)/\1/p" then
> I get "URL: " along with the remote path.

Traditionally empty LHS regexp means "the same as last match". Replace it with "s/^URL: *//p" and you would be Ok.

Nguyen Thai Ngoc Duy· Aug 4, 2007, 00:06 UTC · re: Junio C Hamano · lore

Re: Help a sed noob

Great! Thank you both.
On 8/3/07, Junio C Hamano <gitster@pobox.com> wrote:
Show 19 quoted lines
> "Nguyen Thai Ngoc Duy" <pclouds@gmail.com> writes:
>
> > There is a construct like this in git-parse-remote.sh which makes
> > busybox ash unhappy:
> >
> >                 sed -ne '/^URL: */{
> >                         s///p
> >                         q
> >                 }' "$GIT_DIR/remotes/$1"
> >
> > It complains about "no previous regexp" while gnu sed is ok. Can
> > anyone explain to me what does "s///p" do? GNU Sed info page says
> > nothing about empty regexp. If I replace it with "s/\(.*\)/\1/p" then
> > I get "URL: " along with the remote path.
>
> Traditionally empty LHS regexp means "the same as last match".
> Replace it with "s/^URL: *//p" and you would be Ok.
>
>
-- 
Duy
René Scharfe· Aug 3, 2007, 23:40 UTC · re: Nguyen Thai Ngoc Duy · lore

Re: Help a sed noob

Nguyen Thai Ngoc Duy schrieb:
Show 17 quoted lines
> Hi,
> 
> There is a construct like this in git-parse-remote.sh which makes
> busybox ash unhappy:
> 
>                 sed -ne '/^URL: */{
>                         s///p
>                         q
>                 }' "$GIT_DIR/remotes/$1"
> 
> It complains about "no previous regexp" while gnu sed is ok. Can
> anyone explain to me what does "s///p" do? GNU Sed info page says
> nothing about empty regexp. If I replace it with "s/\(.*\)/\1/p" then
> I get "URL: " along with the remote path.
> 
> By the way, can we use another construct instead? It would be less
> work for me ;-)
You could manually add the previous regular expression, like this:
		sed -ne '/^URL: */{
			s/^URL: *//p
			q
		}' "$GIT_DIR/remotes/$1"
René
martin f krafft· Aug 4, 2007, 10:31 UTC · re: Nguyen Thai Ngoc Duy · lore

Re: Help a sed noob

also sprach Nguyen Thai Ngoc Duy <pclouds@gmail.com> [2007.08.04.0122 +0200]:
>                 sed -ne '/^URL: */{
>                         s///p
>                         q
>                 }' "$GIT_DIR/remotes/$1"
Looks like it prints the first matching line:
  grep '^URL: *' | head -1
-- 
martin;              (greetings from the heart of the sun.)
  \____ echo mailto: !#^."<*>"|tr "<*> mailto:" net@madduck
 
quantum mechanics: the dreams stuff is made of.
 
spamtraps: madduck.bogus@madduck.net
Jeff King· Aug 4, 2007, 11:50 UTC · re: martin f krafft · lore

Re: Help a sed noob

On Sat, Aug 04, 2007 at 12:31:26PM +0200, martin f krafft wrote:
Show 9 quoted lines
> also sprach Nguyen Thai Ngoc Duy <pclouds@gmail.com> [2007.08.04.0122 +0200]:
> >                 sed -ne '/^URL: */{
> >                         s///p
> >                         q
> >                 }' "$GIT_DIR/remotes/$1"
> 
> Looks like it prints the first matching line:
> 
>   grep '^URL: *' | head -1
No, it prints everything _except_ "URL: *" from the first matching line.
-Peff
martin f krafft· Aug 4, 2007, 12:18 UTC · re: Jeff King · lore

Re: Help a sed noob

also sprach Jeff King <peff@peff.net> [2007.08.04.1350 +0200]:
> No, it prints everything _except_ "URL: *" from the first matching line.

I am convinced we could submit this to the Obfuscated Code Contest. :)

The behaviour is absolutely unclear from the manpage and defies my logic. Can you elaborate a bit, even though this is off-topic?

-- 
martin;              (greetings from the heart of the sun.)
  \____ echo mailto: !#^."<*>"|tr "<*> mailto:" net@madduck
 
kill ugly radio
                                                        -- frank zappa
 
spamtraps: madduck.bogus@madduck.net
Simon 'corecode' Schubert· Aug 4, 2007, 12:26 UTC · re: martin f krafft · lore

Re: Help a sed noob

martin f krafft wrote:
Show 5 quoted lines
> also sprach Jeff King <peff@peff.net> [2007.08.04.1350 +0200]:
>> No, it prints everything _except_ "URL: *" from the first matching line.
> 
> I am convinced we could submit this to the Obfuscated Code Contest.
> :)
This is basic sed scripting.
> The behaviour is absolutely unclear from the manpage and defies my
> logic. Can you elaborate a bit, even though this is off-topic?
-ne means "don't print, execute the following code".

/.../ should be clear, { starts a "function list" s// is "match last regexp, so s/// is "match last regexp and replace with empty string. flag "p" to function "s" means "print if matched" q is "quit".

that's really straight forward and all documented in my sed(1).
cheers
  simon
-- 
Serve - BSD     +++  RENT this banner advert  +++    ASCII Ribbon   /"\
Work - Mac      +++  space for low €€€ NOW!1  +++      Campaign     \ /
Party Enjoy Relax   |   http://dragonflybsd.org      Against  HTML   \
Dude 2c 2 the max   !   http://golden-apple.biz       Mail + News   / \
martin f krafft· Aug 4, 2007, 13:56 UTC · re: Simon 'corecode' Schubert · lore

Re: Help a sed noob

also sprach Simon 'corecode' Schubert <corecode@fs.ei.tum.de> [2007.08.04.1426 +0200]:
> s// is "match last regexp, so s/// is "match last regexp and replace with 
> empty string.

This fact is not in the manpage, AFAICT, at least not on Debian systems.

-- 
martin;              (greetings from the heart of the sun.)
  \____ echo mailto: !#^."<*>"|tr "<*> mailto:" net@madduck
 
due to lack of interest tomorrow has been cancelled.
 
spamtraps: madduck.bogus@madduck.net
David Kastrup· Aug 4, 2007, 14:06 UTC · re: martin f krafft · lore

Re: Help a sed noob

martin f krafft <madduck@madduck.net> writes:
Show 6 quoted lines
> also sprach Simon 'corecode' Schubert <corecode@fs.ei.tum.de> [2007.08.04.1426 +0200]:
>> s// is "match last regexp, so s/// is "match last regexp and replace with 
>> empty string.
>
> This fact is not in the manpage, AFAICT, at least not on Debian
> systems.

IIRC, this is a traditional _ed_ feature. I don't think it has ever been a traditional part of _sed_, but maybe some implementations have adopted this usage.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum
Jeff King· Aug 4, 2007, 12:40 UTC · re: martin f krafft · lore

Re: Help a sed noob

On Sat, Aug 04, 2007 at 02:18:11PM +0200, martin f krafft wrote:
> The behaviour is absolutely unclear from the manpage and defies my
> logic. Can you elaborate a bit, even though this is off-topic?
The original sed code in question was:
                sed -ne '/^URL: */{
                        s///p
                        q
                }' "$GIT_DIR/remotes/$1"
There are a few things to note:
  1. -n means "do not print lines by default"
  2. sed addresses consist of an address (in this case a regex meaning
     "do this for lines that match the regex") and a command
  3. The braces start a set of commands, so that for lines matching the
     address, we do all of the commands.
  4. An empty matching portion for a regex means "use the last regex".
So this script comes down to:
  - don't write any lines except the ones we match
  - find a line that starts with URL:
    - replace the URL: part with nothing
    - print the result
    - quit
It could be more simply written as:
sed -ne 's/^URL: *//pq'

which uses the substitution as an address, but I don't know whether that was allowed in the original sed.

-Peff

← back to recent threads