I’m working on more bash completions. This time for some of the command line tools Apple provides for sysadmins.
I decided there had to be a way to get a list of the options from the
man page for a tool. After all they are all in there.
So I built a command line piece by piece. As an example let’s get a list of the options (with some caveats) for the tool
pkgbuild. We start with
man pkgbuild | col -b , the
col -b step takes out the special characters
man uses to show bold on screen. Now find all lines containing
grep, I liked
grep -e '--'. If you have a look at the output of that we are getting close.
Next I decided to use
sed to do a find and replace for the option itself. After some playing around I ended up with
sed -e 's#.*\(--[a-zA-Z-]*\).*$#\1#' An important note for young players, it did take some time and a few tries to get that substitution just right. Don’t be afraid and remember Google (and Stack Exchange) are your friends.
First, I should point out an old Unix hand’s trick. Most of the time you see
sed substitution commands using
/ as the separator but sed can use anything but
\ or newline – it uses the first character it sees after the ‘s’. I usually use
# as it makes the
\ used for special characters easier to spot and the string easier to read.
So now we have a look at the find portion of the sed command. The
.* matches a string of zero or more characters, then the
\( is the start of what we want to match. The option starts with
-- and is followed by a string of alpha characters of either case or a
-. Then we end the match with
\) and finish with zero or more characters till the
which is the end of the line. Then all of the line is replaced with what we matched in the find half by the
Now we have a list but it can contain the same option multiple times so we pass it through
uniq. Our final command line is :
man pkgbuild | col -b | grep -e '–-' \ | sed -e 's#.*\(–-[a-zA-Z-]\).*$#\1#' \ | sort | uniq
You may find that you end up with the odd extra line so you should give it a check. If the options only have a single
- in front of them then I found that
grep -e ' -' | sed -e 's/.*\(\s-[az]*\)/\1/' | seems to work quite well, though some man pages want a
\t instead of a space in that grep command.
You will notice that this leaves the
-- in place. I like that as a check of my command line work and it’s easily removed in our editor.
If you are a BBEdit user then you can add
| bbedit at the end for the output to open straight into a new BBEdit window. Sweet. Oh, did you know that the
bbedit command line tool has a
—-resume flag? Put this in your EDITOR shell variable and when you close the window after editing your
git commit message it will take you back to your shell window. So I have
export EDITOR='bbedit -w —resume in my
Of course, in the time it took me to develop the command line and write this blog post
I could have written several bash completion scripts, but where’s the fun in that?