Deutsch   English   Français   Italiano  
<vk6mam$3lsj$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Janis Papanagnou <janis_papanagnou+ng@hotmail.com>
Newsgroups: comp.unix.shell
Subject: Re: a sed question
Date: Sat, 21 Dec 2024 16:19:48 +0100
Organization: A noiseless patient Spider
Lines: 133
Message-ID: <vk6mam$3lsj$1@dont-email.me>
References: <874j304vv3.fsf@example.com> <vk40gi$3g9sm$1@dont-email.me>
 <87ed21xmb3.fsf@example.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 21 Dec 2024 16:19:50 +0100 (CET)
Injection-Info: dont-email.me; posting-host="f893710cc71c8b9b4e8dbe49b06632d4";
	logging-data="120723"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1/cfVCy8j6FEvO6O8aCn7M0"
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
 Thunderbird/45.8.0
Cancel-Lock: sha1:iYE99L3tA+9pi9+AtAW4wAMpUKI=
X-Enigmail-Draft-Status: N1110
In-Reply-To: <87ed21xmb3.fsf@example.com>
Bytes: 6797

On 21.12.2024 13:17, Salvador Mirzo wrote:
> Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
>> On 18.12.2024 20:46, Salvador Mirzo wrote:
>>> (*) Summary
>>>
>>> I wrote a sed script that makes a line replacement after it finds the
>>> right spot.  So far so good.  Then I added quit command after the
>>> change, but the quit does not seem to take effect---violating my
>>> expectation.  I'll appreciate any help on understanding what's going on.
>>
>> First (before I forget it) change your string comparison '<' to the
>> numerical comparison operator '-lt' as in:   test $# -lt 2 && usage
>> Otherwise, if you get used to using the wrong operator, you may get
>> subtle errors in future if you continue that habit.
> 
> Changed.  Why is it the wrong operator?  It seems it's not the standard
> one---checking just now on the POSIX.1 spec.  I think I just tried it
> out and given it worked as expected, I didn't think of checking it.  I'm
> new to the whole thing.

If you're new be very cautious with Shell; it looks easy to handle
but has a lot subtleties!

You have two sets of comparison operators in Unix shell; strangely
the ones we'd expect to compare numerically (=, !=, <, <=, >, >=)
instead do string comparisons (order of characters). And for the
numeric comparison there's other (-eq, -ne, -lt, -le, -gt, -ge)
operators.

The difference can be observed when comparing numbers in strings
like, say, 11 and 2.
[ 11 -lt 2 ]    # returns false (numeric 11 is greater than 2)
[ 11 '<' 2 ]    # returns true (string 11 comes before string 2)
The first is a comparison [of strings] interpreted as a numeric
entity, the second is a comparison [of strings] as a string with
lexicographic ordering.

Note also that in modern shells there's also $((...)) and ((...))
(arithmetic expansion and the [non-standard] arithmetic command)
available which support a syntax that is less surprising; e.g.

$ echo $(( 11 < 2 ))
$ (( 11 < 2 )) && ...

(without quoted operator and with numerical semantics).

> 
>> Also note that using $* may not work correctly (e.g. depending on
>> filenames [containing spaces] used). The safe form is a quoted  "$@"
> 
> I learned something here.

The point with spaces in filenames is also something elementary
to know; that's why the "$@" needs quoting (and quoted variables
is the rule of thumb for variable expansions [for most cases]).

> [snip code]
> 
>> (Then I was tempted to make a similar comment as Kenny. But...)
> 
> I'm studying and I often go back to the past to see what life was I
> like.  I initially tried to solve the problem with /ed/, but did not
> find a way to insert a string coming from the a shell script's cmdline.
> Then I thought that /sed/ was there to make /ed/ more scriptable.

I very very rarely use 'ed' but I recall to have used it feeding
input from stdin to it, so it is in principle possible to also
feed in expanded shell variables as part of the 'ed' input.

> 
>> WRT your question I'd be interested to understand more about the
>> intention of your original question...
> 
> The intention is mostly in the paragraph above, but the way I study is
> to put things in real-world practice as much as possible.  (When I
> realize the solution is indeed too old to make sense, I replace it.
> Otherwise I stick with it.)  I have a literate programming file that
> contains a chunk that's the version of the program I'm writing.  So when
> you ask the program its version, the information is included in the
> executable, an idea which I like.  I get the version with a git command
> such as

As previously mentioned, 'sed' might not be the best choice for
developing such scripts; you might want to consider to learn 'awk'.

> $ git log --oneline | head -1 | awk '{print $1}'
> 2566d31

With Awk you don't need 'head', it can be done like this

$ git log --oneline | awk 'NR==1 {print $1}'

(For long input files you may want an early exit
  ...| awk 'NR==1 { print $1 ; exit(0) }'
but that just as an aside.)

> 
> So I wanted to include such string in the literate programming file.  At
> first I wrote a solution in the programming language I'm using, but I
> remember seeing many older software using sed for something like that,
> so I decided to study sed a bit.  I read the sed part of Dale Dougherty
> and Arnold Robbins's book "sed & awk", second edition, and I thought sed
> was quite neat and sensible.  What I'm noticing now is that there are
> too many different sed behavior out there to make it sensible to use.
> UNIX systems as a whole are like that, so I'm used to reminding myself
> of using the common subset of everything.  Perhaps the common subset of
> sed is too small.  If I have to use it just for search and replace, then
> perhaps it's not really worth it.

Awk has a powerful large common subset and its base is standardized.
(GNU Awk as a prevalent variant has a couple interesting extensions.)
Since your book covers Awk you should have a look into it. (Arnold
has also another book solely on Awk published, the GNU Awk Manual,
which is also available online.)

> 
>> I mean if you don't trust your 'sed' command just pipe it though
>> 'less'; there's no need to change the 'sed' program just for that.
>>
>> Personally I'd try whether it works (by adding "something" before
>> and also after the desired place in your sample.txt to be sure the
>> other occurrences were not changed), and then just call
>>
>>   sed -e '/<<Release>>=/,+1s/something/sth else/'  sample.txt
>>
>> to see it working.
> 
> Thanks for the excellent instruction!

You're welcome.

Janis