Busque páginas de manual que contengan TODAS las palabras 'foo' 'bar' y 'baz'

12

Me gustaría buscar páginas de manual que contengan TODAS las palabras 'foo', 'bar' y 'baz'.

Si es posible, me gustaría buscar en todo el texto (no solo el nombre y la descripción) de todas las páginas del manual.

Estoy adivinando algo como

man -K foo AND bar AND baz
Tomsai
fuente
funcionó mi guión? usted no dio ningún comentario :)
Polym

Respuestas:

5

Implementé un script que hace exactamente esto.

if [ $# -eq 0 ]; then
  PATTERNS=(NAME AUTHOR EXAMPLES FILES)
else
  PATTERNS=( "$@" )
fi

[ ${#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
  done

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

Supongo que fue una pérdida de tiempo :(

Editar: Parece que

man -K expr1 expr2 expr3

no funcionó?

Editar: puede pasar los scripts ahora sus términos de búsqueda a través de ./script foo bar

polimero
fuente
Parece que un guión es la única forma después de todo.
Graeme
2
Extraño pero ^ cierto ^ - pero fue divertido votar por una pérdida de tiempo ...
mikeserv
El uso de diferentes argumentos simplemente lo hace or, solo pensé que era andporque no lo probé correctamente.
Graeme
3

Algunas reflexiones sobre este script:

  • Utilizando manpathpara obtener la (s) ubicación (es) de las páginas man. Si agrego /home/graeme/.cabal/bina mi PATH, manpath(y man) encontrará páginas de manual en /home/graeme/.cabal/share/man.

  • Use man para descomprimir y formatear las páginas antes de buscar, de esta manera solo está buscando el texto man y no ningún comentario, etc. en el archivo sin formato. El uso manpotencialmente tratará con múltiples formatos.

  • Guardar las páginas formateadas en un archivo temporal evitará múltiples descompresiones y debería acelerar las cosas significativamente.

Aquí va (con bashy GNU encontrar):

#!/bin/bash

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
      fail=true
      break
    fi
  done

  if [ -z "$fail" ]; then
    file=${file##*/}
    printf '%s\n' "${file%.gz}"
  fi
done < <(find $(manpath) -type d ! -name 'man*' -prune -o -type f -print0)
Graeme
fuente
2

No es tan completo como la respuesta de @ polym, pero iba a sugerir algo como

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)

Tenga en cuenta que agregué un -winterruptor (coincidencia de palabras) al greps- que puede no ser lo que desea (¿desea incluir coincidencias como foo lish y nut bar ?)

conductor de acero
fuente
Muy amable de tu parte preguntar.
mikeserv
0

Este enfoque no se ha probado pero es bastante simple (estúpido simple) y espero que funcione, incluso si es ineficiente:

#!/bin/bash

if [ "$#" -eq 0 ]; then
  echo "Provide arguments to search all man pages for all arguments." >&2
  echo "Putting rare search terms first will improve performance." >&2
  exit
fi

if [ "$#" -eq 1 ]; then
  exec man -K "$@"
fi

pages=( $(man -wK "$1") )
shift
while [ "$#" -gt 1 ]; do
  pages=( $(zgrep -l "$1" "${pages[@]}") )
  shift
done
exec man "${pages[@]}"
Comodín
fuente