Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 676
  • Last Modified:

Apropos for commands only?

When I'm looking for commands to do an operation, I sometimes use apropos.  The problem is that apropos will list not just unix commands, but also C APIs as well.  There are plenty C APIs, and they easily outnumber commands listed.

My question:  is there a way to essentially do an apropos on commands only?

I'm not just trying to do a one line listing of commands (for example, if I wanted this for ls I'd do an "apropos '^ls('").  I am trying to get some kind of command or script that I can use that would accomplish searching the context of command descriptions as well, something I think apropos can be really good at.  Maybe I'm just forgetting or missing something really obvious here.

coder
0
coder1313514512456
Asked:
coder1313514512456
  • 12
  • 6
  • 4
  • +3
9 Solutions
 
arnoldCommented:
You could try running which "command".

This will based on your path return the command's location.
apropos is similar to man -k "command"
keyword search in the manual pages.
It returns all the references it has to address your query.

I'm not really sure what you are looking to do.

0
 
omarfaridCommented:
apropos looks in an index of man pages, and I am not sure if that index can be rebuilt to include man pages of commands only. Look into man page of apropos and see if that is possible
0
 
coder1313514512456Author Commented:
arnold:

Essentially my point is that apropos is nice because it returns a list of descriptions and you can basically grep on those descriptions.  I still want to grep on those descriptions, but I just want results that are unix commands.  So I want any results that are from the API list.

Does that clarify my objective?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
coder1313514512456Author Commented:
omarfarid:

Doesn't look like apropos man page really contains much of anything.  I suppose I could try to focus on rebuilding the man pages with only commands, but I'm not even sure how to begin going about to do this.  If memory serves, the man pages are interspersed with both unix command line commands and C APIs.  But I could certainly have that wrong.

0
 
omarfaridCommented:
what flavor of unix do you have?
0
 
omarfaridCommented:
I could think of filtering the results since apropos returns the section name along with the line and then you could pass it through grep to filter the other sections you don't want
0
 
coder1313514512456Author Commented:
(I'm looking for a general unix solution here, I've encountered it on enough flavors to be an annoyance.  But for examples sake, let's say darwin/os x.)

The thing with grepping on section names is that there are plenty of C APIs in all the sections, it appears.  Unless there's some kind of subsection or categorization I don't know about.  And there's certainly plenty I don't know about.

0
 
ozoCommented:
you could grep the output for  '(1)'
0
 
gheistCommented:
exactly like you said:
| grep '(1)'
0
 
arnoldCommented:
Well if you are using grep/script.
You can first grep for items that match your needs.
You can then pass that first item in the response which is either a command or a C/C++ etc. function.
Run a which name.  IF it is in the path, it is a command print out the line , other wise go to the next skip it.

Basically you create a script that uses apropos to get responses and then using the responses faret out

#!/bin/bash
 
if [ -z "$1" ]; then # check to make sure they provided what to search for
echo "Usage: $0 keyword"
exit
fi
apropos $1 | while read a; do
#set will declare the space separated items starting from $1 ->$n items 
set $a 
which $1 2>/dev/null >/dev/null
if [  "$?" -eq "0" ] ; then # check that this is an existing command using the status of the execution of the which command. 
echo "$a"
done

Open in new window

0
 
omarfaridCommented:
I have solaris and linux and both shows section 1 for user commands and section 8 for admin commands

try to put this in a script file and make it executable (and may be in your bin dir)

apropos $1 | egrep '(1)|(8)'

you can run it as

myscript word
0
 
coder1313514512456Author Commented:
ozo, gheist, omarfarid:  Although (1) and (8) do appear for commands, the problem is that they don't filter the other way, that is, they also contain C APIs and I'd be stuck with my same problem (although quite diminished, so thanks!)
arnold:  THAT looks like a really, really, good idea.  I can't try it out right now but by first blush it looks like you may just have solved my problem.  Of course!   Which it, and if it doesn't which, it's not a command.  Brilliant.
I'll get back to you geniuses.  Thanks again everybody.
 
 
 
0
 
coder1313514512456Author Commented:
Arnold, you are truly a talented individual.  The idea to execute a which on the first column of the apropos result list works.

I had to tweak your script just a little (you were doing a which on the column result, so it would try commands like "ls(1)" instead of "ls"), and it works perfectly.  It also shows that there are commands defined in other sections from 2 through 7, in addition to sections 1 and 8.  And this makes it really easy to also see what kinds of commands are in each section, like:   2: chmod,kill,mkdir;  3: login, logout, time;  4: ip6, route, tty;  5: crontab, passwd, uuencode;  6: banner;  7: hostname, etc.

The only thing it doesn't do (yet, anyway) is parse the apropos listing if there are commands that are listed in a comma delimited group.  Know what I mean?  So like, if apropos returns a group and then defines them, and this grouping starts with a C API but the group contains a command, the group will be ignored.

I'm going to keep this question open a little longer in case anyone can sort out the grouping problem.  I guess what you would have to do is loop as long as the apropos column you're examining ends with a comma.  Ideally only the commands of the group would be listed, but this could get complex, at least from a scripting standpoint.

I'm including the code so far.


The following "command-only apropos" works in OS X 10.5.6-9G55 (Darwin) bash 3.2.17(1), however, it lists entire apropos groups if the first in the group is a command, and ignores groups entirely if the first in the group is a C API!
 
#!/bin/bash
 
if [ -z $1 ]
        then
        echo "Usage: $0 keyword";
        exit;
fi
 
apropos $1 | while read a
        do  
        set $a
        which `echo $1 | awk '{ print substr($1, 1, index($1, "(")-1)}'` >/dev/null 2>&1
        if [ "$?" -eq "0" ]
                then
                echo "$a"
        fi  
done

Open in new window

0
 
arnoldCommented:
Post a sample output of apropos that you mentioned.
apropos on systems usually returns:
ls (1) etc.

It is not that difficult to incoporate a check for a comma in the first elemet. and then run it through a for loop or split the group on a comma. splitting can be done in a perl one liner.

0
 
coder1313514512456Author Commented:
Sure.  Here's an example of apropos output, you can see that in Darwin/Mac OS X the parenthesis is immediately next to the command.  Is a split that difficult to do in awk?  I'd prefer awk (or sed) to perl only because it seems that perl isn't necessarily distributed with all flavors of unix and unix-like OSes.  (Though I think they certainly should be!  :) )

Also: ozo, gheist, and omarfarid:  I finally get what you are saying now.  The man pages for Linux and Solaris are organized differently than OS X and they have it so that user (1) and admin (8) commands are grouped in those sections, that makes a lot of sense and is good to know for when I'm using those systems.  And I could have sworn I used a system once that had an apropos switch option to list commands (like apropos -k or something?  An old Unix on HP or an HP/UX?).

Thanks again guys.

Example of grouping and apropos output without space near paren in OS X:
 
$ apropos 'print lines matching a pattern'
grep(1), egrep(1), fgrep(1) - print lines matching a pattern

Open in new window

0
 
arnoldCommented:
It might be easier to setup a perl script to handle this type of issue or add additional logic to check the length of the response.  I have to think on what the better approach would be.
0
 
coder1313514512456Author Commented:
I would like to avoid perl if I can.  (I do appreciate perl!)

It would appear the awk has a split procedure that I totally forgot about.  I can't look at this right now, I'll have to revisit it in a little bit.
0
 
svsCommented:
"Although (1) and (8) do appear for commands, the problem is that they don't filter the other way, that is, they also contain C APIs"

That shouldn't be happening. Try this:

apropos man | egrep '\([18]\)'

( and ) have special meaning in egrep, they have to be escaped with \
0
 
coder1313514512456Author Commented:

sys:

In my version of OS X (now 10.5.7/9J61-Darwin 9.7.0), some examples of some (1) man pages that are not commands include stuff like bash built in commands (see builtin) like alloc, shift, source, stop, etc., and file stuff like finger.conf (which even though it is 5 will often show up on 1, again just an example),  And of course there's always commands that just aren't installed but will show in apropos (but the _which_ command does nicely filter them out via Arnold's script).

I'm still trying to get time together to work on the awk split idea.

Arnold:  Is this -very- easy in perl, or is it the case that it just can be done?  Do you prefix all perl scripts with "perl" or something?

0
 
arnoldCommented:
In some way the grouping you got is because what you were searching for matched multiple manual pages.  The grouping response returned manual pages that have the content you were looking for.  If the commands themselves are included in the response, I would skip the grouped line as of little or no consequence.
text spliting is simpler with perl, you could use bash, sed to replace the comma with a space and then run a for loop.
for i in $test
.

$list=echo $a | sed -e 's/\,/ /'g
for i in $list

The problem is that analyzing group, you will not have the explanation of the command as you would otherwise.

Perl is fairly simple
@array=split(/,/,$variable);
$#array  will return the number of elements in the array.



0
 
coder1313514512456Author Commented:
So Arnold what you are saying is I would have to make sure I nabbed the description with the group, then output each name with an appended description.
And the description, I suppose, would be defined as starting with two spaces and ending with $ endline?
 
 
 
0
 
arnoldCommented:
The grouped items are really not commands but references to manual pages that matched your search criteria.
apropos 'some text in describing function'
item1(1), item2(2), item3(1) - some text in describing function
item1 item1(1) - some text in describing function
item2 item2(2) - some text in describing function
item3 item3(1) - some text in describing function


You are not losing any data/commands by ignoring the grouped manual pages line.

Since the information is not lost by ignoring the grouped data, the added parsing/logic to evaluate the grouped data adds unnecessary checks.

Logically the grouped output is not a list of commands but a list of manual pages.

If you really want to incorporate the group into your command:
replace the which line with:
which `echo $a |awk -F\- ' { print $1 } ' | sed -e 's/,//g' -e 's/([0-9]*)//g'`
What the above will do is split on the - and take the first item.
sed will strip out the commas first and then strip the manual page section.
If you want to maintain the description, you should assign the awk -F\- ' {print $2 } to a variable.
0
 
svsCommented:
The perfect is the enemy of the good.  apropos | egrep one-liner is good enough, why bother?
0
 
coder1313514512456Author Commented:
sys - apropos | egrep is close but it doesn't entirely work on my system.  But I am very satisfied with the responses I've received.
I'm going to close this.  Thanks everyone, especially Arnold!
 
0
 
coder1313514512456Author Commented:
Thanks everyone, you guys are great!
0
 
coder1313514512456Author Commented:
sys:  Let me just say one more thing here, that I totally agree with you that "perfect is the enemy of the good".  It is far too easy to gold plate code when you can just get what you need, much more efficient.
I didn't really see a way to comment to users directly (nothing in the profile areas), so that's why I'm writing this here.
 
 
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 12
  • 6
  • 4
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now