From: Ed Morton on
On Sep 28, 10:21 am, Igor Pozgaj <ipoz...(a)nospam.fly.srk.fer.hr>
wrote:
> On Sun, 27 Sep 2009 20:48:13 +0000, Chris F.A. Johnson wrote:
> > On 2009-09-27, Igor Pozgaj wrote:
> >> On Fri, 25 Sep 2009 13:31:56 -0700, Ed Morton wrote:
>
> >>> sed is a great tool for simple substitutions on a single line, for
> >>> anything else use awk, perl, etc.
>
> >>> awk '/^\(/{ h=$0;next } { print $0,h }' file
>
> >> FUD
>
> >> sed '/(/{h;d};G;s/\n/ /' input.txt
>
> >     I think you just demonstrated Ed's point.
>
> >     (And that's not standard sed syntax; it will not work with many
> >     versions of sed.)
>
> His arguments are ridiculous, for beginner both syntaxes are equally
> unreadable and look like a bunch of hieroglyphs. Why do you think it's
> harder to remember the meaning of command "h" (hold) in sed than the
> meaning of the special variable $0 in awk?
>

It's not just one character, though, is it? It's a whole chain of them
in various magical configurations (e.g. even in that very small
example you had "h", "d", "G", and "s"), and a totally different chain
of them to do a conceptually very similair thing or even just
implement the slightest change in the requirements.

For example, looking at the sed one-liners recently posted:

# insert a blank line above every line which matches "regex"
sed '/regex/{x;p;x;}'
awk '{print (/regex/ ? "\n" : "") $0}'

# insert a blank line below every line which matches "regex"
sed '/regex/G'
awk '{print $0 (/regex/ ? "\n" : "")}'

The sed solution invoves a chain of "x"s, semicolons and "p"s to
insert a line above a regex but a "G" to insert a line below it,
whereas the awk solution simply and consistently is just to add a
blank line before or after the line containing the regex.

Or how about:

# align all text flush right on a 79-column width
sed -e :a -e 's/^.\{1,78\}$/ &/;ta'
awk '{printf "%79s\n",$0}'

where we see several characters in non-obvious comsbinations in the
sed solution whereas the awk soltution is just to print the line in a
79-character wide string.

Or if we get even slightly complex:

# 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
awk 'found {print preLine "\n" hitLine "\n" $0; found=0}
/regexp/ {preLine=prev; hitLine=NR " " $0; found=1}
{prev=$0}'

I mean, seriously - "{=;x;1!p;g;$!N;p;D;}" ????

And then what if in future your requirements changed and you had to,
say, change the text on the line containing the regex to replace the
first occurrence of "foo" with a count of the number of characters in
the line? You'd just update the awk solution to:

awk 'found {print preLine "\n" hitLine "\n" $0; found=0}
/regexp/ {preLine=prev; sub(/foo/,length); hitLine=NR " " $0;
found=1}
{prev=$0}'

I dread to think what the updated sed script would look like and, I
could be wrong as after 25 years of using it I really have no idea how
to do that in sed, but I doubt if it'd even resemble the original.

Ed.
From: Maxwell Lol on
Ben Bacarisse <ben.usenet(a)bsb.me.uk> writes:

> I think you'd do more good by leaving the insults to one side and
> posting a sed solution.

That requires thinking.
It's easier to flame than to think.
From: Maxwell Lol on
Igor Pozgaj <ipozgaj(a)nospam.fly.srk.fer.hr> writes:

>>> sed '/(/{h;d};G;s/\n/ /' input.txt
>>
>> I think you just demonstrated Ed's point.
>>
>> (And that's not standard sed syntax; it will not work with many
>> versions of sed.)

I disagree. I have taught others sed in the past, and I still have to think
about the sed syntax and what it does.

$0 means the "entire line".

Can you explain what G does in 2 words?

I can read 10-year-old AWK scripts and follow them easily.
That's not true of sed.

From: Chris F.A. Johnson on
On 2009-09-29, Maxwell Lol wrote:
> Igor Pozgaj <ipozgaj(a)nospam.fly.srk.fer.hr> writes:
>
>>>> sed '/(/{h;d};G;s/\n/ /' input.txt
>>>
>>> I think you just demonstrated Ed's point.
>>>
>>> (And that's not standard sed syntax; it will not work with many
>>> versions of sed.)
>
> I disagree.

Whom do you disagree with? Me or Igor?

I was saying that Igor's script demonstrates what Ed was saying
about sed, that it is best kept to very simple scripts such
as search and replace.

> I have taught others sed in the past, and I still have to think
> about the sed syntax and what it does.
>
> $0 means the "entire line".
>
> Can you explain what G does in 2 words?

No. Not that being able to explain it in two words is any
indicator.

> I can read 10-year-old AWK scripts and follow them easily.
> That's not true of sed.

I agree.


--
Chris F.A. Johnson, author <http://cfaj.freeshell.org/shell/>
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
===== My code in this post, if any, assumes the POSIX locale
===== and is released under the GNU General Public Licence
From: Maxwell Lol on
"Chris F.A. Johnson" <cfajohnson(a)gmail.com> writes:

> On 2009-09-29, Maxwell Lol wrote:
>> Igor Pozgaj <ipozgaj(a)nospam.fly.srk.fer.hr> writes:
>>
>>>>> sed '/(/{h;d};G;s/\n/ /' input.txt
>>>>
>>>> I think you just demonstrated Ed's point.
>>>>
>>>> (And that's not standard sed syntax; it will not work with many
>>>> versions of sed.)
>>
>> I disagree.
>
> Whom do you disagree with? Me or Igor?


Sorry Chris. I mis-quoted. I agree with you, and disagree with Igor.

>> $0 means the "entire line".
>>
>> Can you explain what G does in 2 words?
>
> No. Not that being able to explain it in two words is any
> indicator.

My point is that even simple sed commands like G are quite complex.
I can explain $0 in two words. Explaining what G does is not as simple.