💾 Archived View for jsreed5.org › log › 2021 › 202110 › 20211012-two-uses-for-grep.gmi captured on 2024-06-16 at 13:12:51. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2021-12-04)

-=-=-=-=-=-=-

Two Uses for grep

2021-10-12

---

While working on a bash script today, I ran into two tasks for which (GNU) grep provided an elegant solution.

The first task was to check if a nonempty string contained only digits, not all zero, with leading zeroes allowed. If the check passed, the string remained the same; otherwise the string was emptied. This check could be done in regex by using negative lookahead:

^(?!0+$)\d+$

However, I couldn't use this regex directly with bash builtins such as double brackets or the expr command. The shell treated the exclamation point in the lookahead as a history expansion before evaluating the regex, which of course threw an error. My solution involved echoing the string and piping it into grep:

string="$(echo "$string" | grep -P '^(?!0+$)\d+


)"

The second task was to take a number and print a block of text corresponding to the number from a file. The blocks had some regularity: each block started with a line containing four pound signs, one space, and the number zero-padded to 8 digits, and each block ended with a line containing three dashes. Given a (non-padded) number specified as $number, the following command did the trick in one line:

eval "grep -oPz '(?s)#### $(printf "%08d" $number).*?\n---\n' file"

The eval was needed to allow the shell to evaluate the printf statement before running the grep.

I have a few quirks when writing scripts. One of them is that I enclose everything I can in double quotes. That probably hinders me in cases like this, but I don't always feel safe passing data that isn't protected by quotes. Maybe as I improve my scripting skills, one day I'll feel comfortable dropping the double-quote training wheels.

---

Up One Level

Home

[Last updated: 2021-10-28]