Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'd like to search for man pages which contain ALL of the words 'foo', 'bar' and 'baz'.

If possible, I'd like to search through all text (not just name & description) of all man pages.

I'm guessing something like

man -K foo AND bar AND baz
share|improve this question
did my script work? u didn't give any feedback :) – polym Jun 24 '14 at 3:21
up vote 5 down vote accepted

I implemented a script that does exactly this.

if [ $# -eq 0 ]; then
  PATTERNS=( "$@" )

[ ${#PATTERNS[@]} -lt 1 ] && echo "Needs at least 1 pattern to search for" && exit 1

for i in $(find /usr/share/man/ -type f); do
  TMPOUT=$(zgrep -l "${PATTERNS[0]}" "$i")
  [ -z "$TMPOUT" ] && continue

  for c in `seq 1 $((${#PATTERNS[@]}-1))`; do
    TMPOUT=$(echo "$TMPOUT" | xargs zgrep -l "${PATTERNS[$c]}")
    [ -z "$TMPOUT" ] && break

  if [ ! -z "$TMPOUT" ]; then
    #echo "$TMPOUT" # Prints the whole path
    MANNAME="$(basename "$TMPOUT")"
    man "${MANNAME%%.*}"

Guess it was a waste of time :(

Edit: Seems like

man -K expr1 expr2 expr3

didnt work?

Edit: You can pass the scripts now your search terms via ./script foo bar

share|improve this answer
Looks like a script is the only way after all. – Graeme Jun 15 '14 at 16:30
Strange but ^true^ - but it was fun to vote for a waste of time... – mikeserv Jun 15 '14 at 16:38
Using different arguments just does or, I only thought it was and because I didn't test it properly. – Graeme Jun 15 '14 at 16:41
Thanks very much for this – Tomsai Jul 1 '14 at 18:30

Not as complete as @polym's answer, but I was going to suggest something like

while IFS= read -rd $'\0' f; do 
  zgrep -qwm1 'foo' "$f" && \
  zgrep -qwm1 'bar' "$f" && \
  zgrep -qwm1 'baz' "$f" && \
  printf '%s\n' "$f"
done < <(find /usr/share/man -name '*.gz' -print0)

Note that I added a -w (word match) switch to the greps - which may not be what you want (do you want to include matches like foolish and nutbar?)

share|improve this answer
Very polite of you to ask. – mikeserv Jun 15 '14 at 17:33

A few thoughts on scripting this:

  • Using manpath to get the location(s) of the man pages. If I add /home/graeme/.cabal/bin to my PATH, manpath (and man) will find man pages in /home/graeme/.cabal/share/man.

  • Use man itself to decompress and format the pages before searching, this way you are just searching the man text itself and not any comments etc in the raw file. Using man will potentially deal with multiple formats.

  • Saving the formatted pages in a tempfile will avoid multiple decompressions and should speed things up significantly.

Here goes (with bash and GNU find):


set -f; IFS=:
trap 'rm -f "$temp"' EXIT
temp=$(mktemp --tmpdir search_man.XXXXXXXXXX)

while IFS= read -rd '' file; do
  man "$file" >"$temp" 2>/dev/null

  unset fail
  for arg; do
    if ! grep -Fq -- "$arg" "$temp"; then

  if [ -z "$fail" ]; then
    printf '%s\n' "${file%.gz}"
done < <(find $(manpath) -type d ! -name 'man*' -prune -o -type f -print0)
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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