I am trying to auto-generate tab-completions for different commands. I am piping man pages for different commands into awk, then searching for command line options (eg. -shortopt --long-option) printing each on a separate line:

for (i=1;i<NF;i++){
    if(match("\<-[0-9a-zA-Z_-]\+\>", $i)){
        print $i

For some reason this refuses to work. With single backslashes, awk warns about ignoring the escape sequence \<, then treats it as a literal \\<. If I double the backslashed, awk then refuses to actually match against the appropriate pattern (which works if I open the man page in vim, then run that pattern, so I think the pattern should be correct). The above code snippet lives in a file, then I invoke it with man {section} {page} | awk -f find-options.awk, so I think I can rule out issues with the command string being parsed multiple times by both bash and awk (as in awk FS with back slashes) as awk should be reading the script file directly.

  • 2
    You might get better results searching the *roff source markup – roaima Sep 29 '19 at 15:15
  • Yes, as roaima says, it would be easier to parse the roff sources than to parse the generated manual. But there are a few competing roff macro sets for typesetting manuals, so a solution that parses roff sources would have to take Linux man sources and mandoc sources into account (at least) to be generally useful. When you parse generated manuals (as in the question), you may want to take into account that the resulting text may use control sequences for doing highlighting and bold text etc. – Kusalananda Sep 29 '19 at 15:20
  • 1
    I didn't understand what you are looking for as a result but as a Hint in order to use a word boundaries ability in awk, you could use a variable to define your regex then use that variable and find a match against of that like man …| awk 'BEGIN{myRegex="\\<-[0-9a-zA-Z_-]+\\>";} {for(...) if(match($i, myRegex)) do_somehintg}' – αғsнιη Sep 29 '19 at 16:49
  • 1
    You have the match() arguments in the wrong order, assuming that first string is supposed to be your regexp. If so then you're also using a dynamic regexp "..." instead of a static regexp /.../ and so need to double the escapes to account for 1 being consumed by the process of converting the string to a regexp. Also \< is gawk-only - are you using gawk? – Ed Morton Sep 29 '19 at 22:52

Your Answer

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

Browse other questions tagged or ask your own question.