Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to look for a flag in a man page?

I'm trying to come up with a way to find a specific flag in a man-page. Usually, I type '/' to search for something, followed by something like '-Werror' to find a specific flag. The thing is though that there are man-pages (gcc is the one motivating me right now) that have a LOT of references to flags in their text, so there are a lot of occurrences.

It's not that big of a deal, but maybe it can be done a bit better. I thought of looking for something like '-O\n' but it didn't work (probably because the man program doesn't use C escapes?) Then I've tried something like man gcc | grep $'-O\n', since I kind of recall that a single-quoted string preceded by a dollar sign haves bash interpret common C escapes... It' didn't work, grep echoed the whole man-page.

That's what has brought me here: why? or rather, can this be done?

like image 802
ferhtgoldaraz Avatar asked Oct 05 '13 14:10

ferhtgoldaraz


People also ask

How to search for a flag in a man page?

The search starts at the first line displayed (but see the -a and -j options, which change this). So one could try and look for '-O$' in a man-page to find a flag that lives alone in it's own line.

What do you look for in a man if you're married?

Here are 15 green flags to look for in a man if you’re looking to get married. 1. He respects you, your choices, and your boundaries. He treats you like he would treat his mother or sister: with the utmost respect. If you express your feeling or preference about anything at all, he listens to you, makes notes, and takes action on them.

How to find a flag that lives alone in it's own line?

So one could try and look for '-O$' in a man-page to find a flag that lives alone in it's own line. Although, it is common for a flag to be followed by text in the very same line, so this is not guaranteed to work. The issue with grep and $'-O ' is still a mystery though.

How do I find the pattern of a flag?

The pattern is a regular expression, as recognized by the regular expression library supplied by your system. The search starts at the first line displayed (but see the -a and -j options, which change this). So one could try and look for '-O$' in a man-page to find a flag that lives alone in it's own line.


1 Answers

rici's helpful answer explains the problem with the original approach well.

However, there's another thing worth mentioning:

man's output contains formatting control characters, which interfere with text searches.

If you pipe to col -b before searching, these control characters are removed - note the side effect that the search results will be plain-text too.

However, grep is not the right tool for this job; I suggest using awk as follows to obtain the description of -O:

man gcc | col -b | awk -v RS= '/^\s+-O\n/'
  • RS= (an empty input-record separator) is an awk idiom that breaks the input into blocks of non-empty lines, so matching the option at the start of such a block ensures that all lines comprising the description of the option are returned.

If you have a POSIX-features-only awk such as BSD/OSX awk, use this version:

man gcc | col -b | awk -v RS= '/^[[:blank:]]+-O\n/'

Obviously, such a command is somewhat cumbersome to type, so find generic bash function manopt below, which returns the description of the specified option for the specified command from its man page. (There can be false positives and negatives, but overall it works pretty well.)

Examples:

manopt gcc O          # search `man gcc` for description of `-O`
manopt grep regexp    # search `man grep` for description of `--regexp`
manopt find '-exec.*' # search `man find` for all actions _starting with_ '-exec'

bash function manopt() - place in ~/.bashrc, for instance:

# SYNOPSIS
#   manopt command opt
#
# DESCRIPTION
#   Returns the portion of COMMAND's man page describing option OPT.
#   Note: Result is plain text - formatting is lost.
#
#   OPT may be a short option (e.g., -F) or long option (e.g., --fixed-strings);
#   specifying the preceding '-' or '--' is OPTIONAL - UNLESS with long option
#   names preceded only by *1* '-', such as the actions for the `find` command.
#
#   Matching is exact by default; to turn on prefix matching for long options,
#   quote the prefix and append '.*', e.g.: `manopt find '-exec.*'` finds
#   both '-exec' and 'execdir'.
#
# EXAMPLES
#   manopt ls l           # same as: manopt ls -l
#   manopt sort reverse   # same as: manopt sort --reverse
#   manopt find -print    # MUST prefix with '-' here.
#   manopt find '-exec.*' # find options *starting* with '-exec'
manopt() {
  local cmd=$1 opt=$2
  [[ $opt == -* ]] || { (( ${#opt} == 1 )) && opt="-$opt" || opt="--$opt"; }
  man "$cmd" | col -b | awk -v opt="$opt" -v RS= '$0 ~ "(^|,)[[:blank:]]+" opt "([[:punct:][:space:]]|$)"'
}

fish implementation of manopt():

Contributed by Ivan Aracki.

function manopt 
  set -l cmd $argv[1]
  set -l opt $argv[2] 
  if not echo $opt | grep '^-' >/dev/null
    if [ (string length $opt) = 1 ] 
      set opt "-$opt"
    else
      set opt "--$opt"
    end
  end
  man "$cmd" | col -b | awk -v opt="$opt" -v RS= '$0 ~ "(^|,)[[:blank:]]+" opt "([[:punct:][:space:]]|$)"'
end
like image 70
mklement0 Avatar answered Sep 17 '22 07:09

mklement0