5

I want to find three patterns in a list. I tried typing

$ pip3 list | grep -ei foo -ei bar -ei baz

but the shell throws a broken pipe error and a large Traceback.

How do I grep for multiple patterns passed from a list that is piped to grep?

6
  • That should probably be grep -ie foo -e bar -e baz, no? the expressions should follow the -e Commented Jul 14, 2018 at 18:16
  • @steeldriver can you clarify? I'm not sure what you mean.
    – bit
    Commented Jul 14, 2018 at 18:18
  • 2
    Try pip3 list | grep -ei - you're asking grep to find all lines matching i Commented Jul 14, 2018 at 18:25
  • 2
    That was my point - the order of the i and e matters (because i is just a switch, whereas e expects an argument) Commented Jul 14, 2018 at 18:37
  • 2
    Ahh now its clear why -e must be last and also why -i is needed only once, while -e is needed for every pattern. Good answer.
    – bit
    Commented Jul 14, 2018 at 18:41

2 Answers 2

9

Try:

pip3 list | grep -Ei 'foo|bar|baz'

Here is a real life example from my Arch server:

pip3 list | grep -Ei 'ufw|set'
setuptools 40.0.0 
ufw        0.35   

OS and grep info:

uname -a
Linux archlinux 4.16.6-1-ARCH #1 SMP PREEMPT Mon Apr 30 12:30:03 UTC 2018 x86_64 GNU/Linux

grep --version
grep (GNU grep) 3.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Haertel and others, see <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.
12
  • 2
    Note that egrep is deprecated in favor of grep -E, for what it's worth. Commented Jul 14, 2018 at 18:17
  • 1
    @multithr3at3d: Depends on the system. Solaris for example does not have a grep -E and therefore your only option is egrep. Parenthesis are not required though.
    – jesse_b
    Commented Jul 14, 2018 at 18:18
  • 1
    @multithr3at3d Umm... Ok. That was news to me. I have used egrep forever, and still do.
    – anon
    Commented Jul 14, 2018 at 18:19
  • 1
    @Jesse_b you're right, my comment is in reference to GNU grep. @maulinglawns it still works for historical compatibility Commented Jul 14, 2018 at 18:21
  • 1
    can confirm egrep and grep -E both work.
    – bit
    Commented Jul 14, 2018 at 18:25
8

The reason

grep -ei foo -ei bar -ei baz

does not work is because the semantics for the -e option is -e PATTERN, as in

grep -i -e foo -e bar -e baz

... which is what the command should have looked like. The -i option (for case insensitive matching) will only need to be specified once and will affect all patterns.

With -ei foo you ask grep to look for the pattern i in the file foo.

The "broken pipe" error comes from pip3 trying to write to the end of a dead pipe. The pipe is dead because grep could not find the files foo, bar or baz, and terminated (with three "file not found" errors). The traceback is from pip3 which is a Python program (so it tells you exactly where in the Python code the fault happened on its side).

4
  • Really good explanation, thanks. Related question: if -ei foo is asking grep to look for the pattern i in the file foo then why doesn't it just return a pattern or file not found error, instead of filling up my screen with a Traceback for a broken pipe error.
    – bit
    Commented Jul 14, 2018 at 18:44
  • @MyWrathAcademia grep should have given you a "file not found" error (look at the top, before the traceback). Python programs often give tracebacks on errors. Note that it's pip3 that gives you the traceback, not grep. It does that because you've asked to write to a pipe that nobody is listening at the other end of (grep already died because it couldn't open the files you told it to look in).
    – Kusalananda
    Commented Jul 14, 2018 at 18:52
  • Your right, I didn't see the grep: foo: No such file or directory error before because it was lost in the sea of information, I can't see the others, may be they are there somewhere. Thanks for imparting the knowledge. One more thing, is this Traceback saved anywhere so I know if I have to delete it or is it just passed to stdoutput only?
    – bit
    Commented Jul 14, 2018 at 19:00
  • @MyWrathAcademia The traceback from pip3 is sent to its standard error stream. It is not saved anywhere on file by default.
    – Kusalananda
    Commented Jul 14, 2018 at 19:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .