Hacker News new | ask | show | jobs
by asicsp 1364 days ago
If you'd like to learn more about such grep powers, check out my free ebook [0]

What do you mean by "reverse \K"? Are you aware of lookarounds? Perhaps you meant positive lookahead?

    # match digits only if there is a semicolon afterwards
    $ echo '12; 42,31;100' | grep -oP '\d+(?=;)'
    12
    31

[0] https://learnbyexample.github.io/learn_gnugrep_ripgrep/intro...
2 comments

In vim there is `\zs` and `\ze` where `\zs` is the `\K` equivalent in grep.

Basically

  :%s/hello \zsworld\ze out there/planet/g
would find all `hello world out there` and replace `world` to `planet`.
Consider this:

    grep -P 'start: (\d+) end'
"How do I make it print only the captured group with the number, not the whole line?" is a pretty common Stack Overflow question. The "\K" thing gets rid of the "start: " part, but what about " end"? That's were "reverse \K" would come in handy.
That's where ripgrep's -r/--replace flag comes in handy:

    $ echo 'foobar start: 123 end quuxbar' | rg 'start: ([0-9]+) end'
    foobar start: 123 end quuxbar
    $ echo 'foobar start: 123 end quuxbar' | rg 'start: ([0-9]+) end' -r '$1'
    foobar 123 quuxbar
    $ echo 'foobar start: 123 end quuxbar' | rg 'start: ([0-9]+) end' -or '$1'
    123
That's where lookarounds help:

    grep -oP 'start: \K\d+(?= end)'
`\K` is kinda similar to lookbehind (but not exactly same as it is not zero-width), and particularly helpful for variable length patterns.

If you need to process further, you can make use of `-r` option in `ripgrep` or move to other tools like sed, awk, perl, etc.