2

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?

  • That should probably be grep -ie foo -e bar -e baz, no? the expressions should follow the -e – steeldriver Jul 14 '18 at 18:16
  • @steeldriver can you clarify? I'm not sure what you mean. – MyWrathAcademia Jul 14 '18 at 18:18
  • 2
    Try pip3 list | grep -ei - you're asking grep to find all lines matching i – steeldriver Jul 14 '18 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) – steeldriver Jul 14 '18 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. – MyWrathAcademia Jul 14 '18 at 18:41
5

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>.
  • 2
    Note that egrep is deprecated in favor of grep -E, for what it's worth. – multithr3at3d Jul 14 '18 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 Jul 14 '18 at 18:18
  • 1
    @multithr3at3d Umm... Ok. That was news to me. I have used egrep forever, and still do. – maulinglawns Jul 14 '18 at 18:19
  • 1
    @Jesse_b you're right, my comment is in reference to GNU grep. @maulinglawns it still works for historical compatibility – multithr3at3d Jul 14 '18 at 18:21
  • 1
    can confirm egrep and grep -E both work. – MyWrathAcademia Jul 14 '18 at 18:25
7

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).

  • 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. – MyWrathAcademia Jul 14 '18 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 Jul 14 '18 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? – MyWrathAcademia Jul 14 '18 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 Jul 14 '18 at 19:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.