Hacker News new | past | comments | ask | show | jobs | submit login

Let me take these PhD level regex down to elementary school awesome.

I have a process table and I want to grep it for the phrase "banana":

ps auxww | grep banana

root 87 Jun21 0:26.78 /System/Library/CoreServices/FruitProcessor --core=banana

mikec 456 450PM 0:00.00 grep banana

Argh! It also greps for the grep for banana! Annoying!

Well, I'm sure there's pgrep or some clever thing, but my coworker showed me this and it took me a few minutes to realize how it works:

ps auxww | grep [b]anana

root 87 Jun21 0:26.78 /System/Library/CoreServices/FruitProcessor --core=banana

Doc Brown spoke to me: "You're just not thinking fourth dimensionally!" Like Marty, I have a real problem with that. But don't you see: [b]anana matches banana but it doesn't match 'grep [b]anana' as a raw string. And so I get only the process I wanted!




This almost always works, but it won't if the shell expands your bracketed letter. See for example:

    $ echo [b]anana
    [b]anana
    $ touch banana
    $ echo [b]anana
    banana
You can escape the bracket and it will work:

    $ echo \[b]anana
    [b]anana


I tested with zsh, apparently even if there's no matches it still complains.

Escaping works under zsh. My preferred method is single quotes:

    echo '[b]anana'


I remember reading about this trick 20-some years ago, but it's still as good now as it was then.


Which zsh version? On 5.7.1, echo \[b]anana works in both cases


This is really clever... I usually ended up with adding

  | grep -v grep
like in

  ps auxww | grep banana | grep -v grep


this does tend to play havoc with $? values if you're used to using those to test grep's results.


You can always just reverse the greps.


the simple things in life elude me. holy cow. i learned the "tag a grep -v grep" at the end and never looked into refining it. but just flipping the greps? nope, not once did that ever occur to me. thanks


That's a valid concern, but in this case it won't cause problems -- grep exits with 0 if a line was selected; in the case of `grep -v grep` that means there was a line without "grep", which is what we want.

(Also @thewakalix made a good suggestion to reverse the greps.)


except, your grep -v portion will always return a result so $? will also always return 0. even if your grep banana did not find anything.

the reversing the greps will be my new default behavior


Nope, try it out:

  $ printf 'banana\ngrep banana\n' | grep banana | grep -v grep
  banana
  $ echo $?
  0
  $ printf 'grep banana\n' | grep banana | grep -v grep
  $ echo $?
  1
To clarify my previous comment, `grep -v grep` exits with 0 if there was a line without "grep" in the output of `grep banana`.


In bash, you can get the rc of piped things, the var eludes me while walking..


${PIPESTATUS[@]} for a space delimited list of all exit codes, or replace @ with the position in the pipe chain of the specific command you want.

ps auxwww | grep banana | grep -v grep && echo ${PIPESTATUS[1]}

type of thing


You can also set -o pipefail. The first non-zero exit code is returned if there is one.


wow. and here i've been ps auxwww | grep banana | grep -v grep all this time

edit: saw someone else posted this as well. should have known


Messes with the highlighting, you need to tag another | grep banana on the end ;)


but what's wrong with pgrep -f though? I don't want to search for clever trick every time I need to grep a process


pgrep is great, but note that you can still encounter this problem if you run pgrep in parallel -- it will never match its own process, but it will match other pgrep processes.

So for example if you have a script that uses `pgrep -f banana` to search for a "banana" process, and you run that script twice in parallel, pgrep might see the other pgrep process and think "banana" is running even though it isn't.

I was bitten by this :)


I use prep -laf the-wanted-string https://man7.org/linux/man-pages/man1/pgrep.1.html

But nice regex though

Edit : someone already posted that solution https://news.ycombinator.com/item?id=27777901


    ps auxww|sed -n '/ doesnotexist /d;/banana/p'
When/if grep is not available


What systems don’t have grep? Off the top of my head, anything vaguely POSIX compliant would have it, and anything descended from 4th Edition Unix would also have it, which seems like it would cover everything.


"What system don't have grep?"

Emedded systems is one answer.

Toolchains for compiling systems from source is another answer, e.g., NetBSD's toolchain has sed, but not grep.

A third answer is install media. For example, NetBSD install kernels have ramdisks with sed but not grep.

A fourth answer is personal, customised systems. I create small systems that run from RAM. I run these on small computers with limited resources. When one of these computers first boots up, it may not have a "full" set of userland programs. It may not have grep. I am not inclined to use the limited space available to include grep at such an early stage if I can get by with sed.

Hope this answers your question.


The most common cases today are probably Docker containers, which are often based on the most minimal image possible. Alpine doesn't have grep iirc.


> Hope this answers your question.

It does, thanks for the detailed response.


Maybe someone deleted grep by accident? Or maybe you accidentally traveled in time to the 70's and need to use a nearby PDP-11 to calculate a way home? Lots of possibilities.


I give up. I have to know why this works. Please, tell me.


The regex `[b]anana` matches the string "banana". But it does not match the literal string `[b]anana` --- to match that, you'd need something like `\[b\]anana`. The literal string `[b]anana` is what shows up in the process table for grep, and so it doesn't match.


Ooooooh, that's brilliant. You've made the self reference no longer a self reference.


This is really cool. This should also work:

    ps auxww | grep b\\anana


_applause_

Never thought of that. Nice.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: