Miscellaneous ephemera…

Command Line Notes


A couple of weeks ago, I came across these simple bash functions written by Jack Mottram of One Thing Well for managing text notes.

The functions as described in the article are so:

n() { $EDITOR ~/notes/"$*".txt }

nls() { ls -c ~/notes/ | grep "$*" }

Unfortunately, the second function – for retrieving the list of files in the notes directory has two significant shortcomings — it uses ls1 and it will only list files in the top level directory. If you are an inverterate note taker, this plainly won’t scale.

My first attempt at hacking a solution yielded this little beauty:

nls() { tree -Cu --noreport ~/.notes | awk '{print $2,$3}' | tr -d [:digit:] | sed 's/]//'\ 
| cut -d"." -f1 ; }

Which removes ls from the function and allows nested directories, but is needlessly complex and, with four pipes, hideously inefficient inelegant.

After reading up on Awk, particularly Bruce Barnett’s primer, I arrived at something marginally longer but relying solely on the awesome power of awk to make the various transformations I was seeking…

nls() { tree -CR --noreport ~/.notes | awk '{ if (NF==1) print $1; \
else if (NF==2) print $2; else if (NF==3) print "  "$3 }' ; }

An added advantage is that it is scalable irrespective of how deep the directories go. I’m sure that with some more awk-foo I could write a more effective set of conditionals, but this seemed a pretty good start for a simple note taking utility.

Updated 3/11/10

To remove a little of the visual clutter, I amended the awk script to strip the .txt extensions from the output.2

nls () { tree -CR --noreport ~/.notes | awk '{ if ((NR > 1) gsub(/.txt/,"")); \
if (NF==1) print $1; else if (NF==2) print $2; else if (NF==3) printf "  %s\n", $3 }' ;}

And if you really want this to work well, create your .notes directory in a dropbox folder and symlink to it from ~/.notes.

  1. See Parsing ls on Wooledge Wiki.

  2. Obligatory “after” screenshot: