this post was submitted on 07 Jul 2025
4 points (100.0% liked)

Shell Scripting

1495 readers
7 users here now

From Ash, Bash and Csh to Xonsh, Ysh and Zsh; all shell languages are welcome here!

Rules:
  1. Follow Lemmy rules!
  2. Posts must relate to shell scripting. (See bottom of sidebar for more information.)
  3. Only make helpful replies to questions. This is not the place for low effort joke answers.
  4. No discussion about piracy or hacking.
  5. If you find a solution to your problem by other means, please take your time to write down the steps you used to solve your problem in the original post. You can potentially help others having the same problem!
  6. These rules will change as the community grows.

Keep posts about shell scripting! Here are some guidelines to help:


In general, if your submission text is primarily shell code, then it is welcome here!

founded 2 years ago
MODERATORS
 

Let me show you what I mean by giving an example:

# Assume we have this list of increasing numbers
140
141
145
180
190
...

# If we pick 150 as threshold, the output should consist of 145 and all larger values:
145
180
190
...

# In the edge case where 150 itself is in the list, the output should start with 150:
150
180
190
...

I guess one can always hack something together in awk with one or two track-keeper variables and a bit of control logic. However, is there a nicer way to do this, by using some nifty combination of simpler filters or awk functionalities?

One way would be to search for the line number n of the first entry larger than the threshold, and then print all lines starting with n-1. What command would be best suited for that?

Still, I'm also wondering: Can awk or any other standard tool do something like "for deciding whether to print this line, look at the next line"?

(In my use case, the list is short, so performance is not an issue, but maybe let's pretend that it were.)

all 4 comments
sorted by: hot top controversial new old
[–] Ephera@lemmy.ml 2 points 5 hours ago (1 children)

Still, I’m also wondering: Can awk or any other standard tool do something like “for deciding whether to print this line, look at the next line”?

I don't know enough about awk to think this through to the end, but a trick from functional programming, which you might be able to apply here, is to 'zip' the list with itself, offset by one.

So, it might then look like this, for example:

140,141
141,145
145,180
180,190
190,

Of course, in Bash you would probably need to implement the zipping yourself, so it might not save you much effort here...

[–] loveknight@programming.dev 1 points 2 hours ago* (last edited 2 hours ago)

Thank you, in fact I ended up doing something that's mathematically just about that: I have the previous line stored in an auxiliary variable lastline, and it is the evaluation of the current line $0 that determines whether the previous line gets printed.

awk -v threshold=150 'BEGIN {lastline=""}
  (lastline!="" && threshold<$0){print lastline} #the additional check lastline!="" prevents an empty line at the very beginning
  {lastline=$0}
  END{print} #hardcode printing of the very last line, because otherwise it would never be printed
' 

(IIRC, it was a StackOverflow post that led me to this.)

[–] shadow53@programming.dev 1 points 5 hours ago

Algorithmically, I think you'd want to use a binary search algorithm to find the index of the threshold value, or the index of where it should be. Since the value at that index is either the threshold or the first value greater than the threshold, you can check the value at that index and, if not equal to the threshold, subtract one from the index. Then it's a matter of making a subslice of the list of values starting at that index until the end of the list.