| 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