5 ms·
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 ban
by digitalsushi 5y ago
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!
- sandreas 5y agoThis is really clever... I usually ended up with adding | grep -v grep like in ps auxww | grep banana | grep -v grep
- dylan604 5y agothis does tend to play havoc with $? values if you're used to using those to test grep's results.
- thewakalix 5y agoYou can always just reverse the greps.
- dylan604 5y agothe 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
- hddqsb 5y agoThat'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.)
- dylan604 5y agoexcept, 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
- hddqsb 5y agoNope, 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`.
- bbarnett 5y agoIn bash, you can get the rc of piped things, the var eludes me while walking..
- dylan604 5y ago${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
- joombaga 5y agoYou can also set -o pipefail. The first non-zero exit code is returned if there is one.
- sigg3 5y ago_applause_ Never thought of that. Nice.
- jackhalford 5y agobut what's wrong with pgrep -f though? I don't want to search for clever trick every time I need to grep a process
- hddqsb 5y agopgrep 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 :)
- stonewareslord 5y agoThis 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
- srcreigh 5y agoI 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'
- michaelcampbell 5y agoI remember reading about this trick 20-some years ago, but it's still as good now as it was then.
- stonewareslord 5y agoWhich zsh version? On 5.7.1, echo \[b]anana works in both cases
- nick__m 5y agoI use prep -laf the-wanted-string https://man7.org/linux/man-pages/man1/pgrep.1.html 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 https://news.ycombinator.com/item?id=27777901
- selcuka 5y agoThis is really cool. This should also work: ps auxww | grep b\\anana
- 1vuio0pswjnm7 5y agops auxww|sed -n '/ doesnotexist /d;/banana/p' When/if grep is not available
- gnubison 5y agoWhat 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.
- yellowapple 5y agoMaybe 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.
- 1vuio0pswjnm7 5y ago"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.
- ticklemyelmo 5y agoThe most common cases today are probably Docker containers, which are often based on the most minimal image possible. Alpine doesn't have grep iirc.
- gnubison 5y ago> Hope this answers your question. It does, thanks for the detailed response.
- dylan604 5y agowow. 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
- smichel17 5y agoMesses with the highlighting, you need to tag another | grep banana on the end ;)
- mabbo 5y agoI give up. I have to know why this works. Please, tell me.
- tptacek 5y agoThe 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.
- mabbo 5y agoOoooooh, that's brilliant. You've made the self reference no longer a self reference.