Skip to content

Instantly share code, notes, and snippets.

@kerrishotts
Created January 24, 2015 03:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kerrishotts/f23f7000270c7039781b to your computer and use it in GitHub Desktop.
Save kerrishotts/f23f7000270c7039781b to your computer and use it in GitHub Desktop.
Simple note taker and time tracker. Add to path to use anywhere. Tested on OS X 10.10 (BSD).
#!/bin/bash
#
# note v0.1
# Kerri Shotts <kerrishotts@gmail.com>
#
# Add a note to a file (or default file in current directory) with an optional timestamp and other nifty features
# what version are we?
version="0.1"
# A POSIX variable
OPTIND=1 # Reset in case getopts has been used previously in the shell.
# Output file. I like to create a local text file in the local directory. If you prefer a global file by default,
# use ~ instead of the dot.
output_file="./my-notes.txt"
# If 1, a timestamp will be generated
put_timestamp=0
# If 1, a new task is started
begin_task=0
# if 1, a task will be ended, and the difference between the start and end of the task is computed
end_task=0
# if 0, the file is overwritten
append=1
# if 1, the utility is extremely verbose.
verbose=0
# the message to store
message=""
# the first character. By default a ".". When a task begins, ">", and when a task ends, "<"
firstchar="."
# @method v
# @param {string} string to display, if $verbose is 1
function v {
if [ $verbose -eq 1 ]; then
echo "note: $1";
fi
}
# @method write_to_file
# @param {string} string to write to the output file. If $append is zero, the file is overwritten.
function write_to_file {
if [ $append -eq 0 ]; then
v "overwriting $output_file";
printf "$1\n" > $output_file;
append=1;
else
printf "$1\n" >> $output_file;
fi
v "added $1 to $output_file"
}
# parse te command line
# command line switch processing stolen from http://stackoverflow.com/a/14203146/741043
while getopts "h?vVtOBEf:" opt; do
case "$opt" in
h|\?)
echo "";
echo "note v$version";
echo "Kerri Shotts <kerrishotts@gmail.com>";
echo "";
echo "Usage:";
echo " $0 [options] \"note\""
echo "";
echo "Switches:";
echo " -h, -?: show this help";
echo " -f: output file ($output_file)";
echo " -t: generate timestamp";
echo " -O: overwrite (default is to append)";
echo " -B: begin task; generates timestamp";
echo " -E: end task; computes time difference";
echo " -v: verbose";
echo " -V: version";
echo "";
echo "Note: To prevent expansion, you should quote your note.";
echo "";
exit 0;
;;
v) verbose=1
;;
V) echo "$version";
exit 0;
;;
f) output_file=$OPTARG
;;
t) put_timestamp=1;
v "will write timestamp";
;;
B) begin_task=1;
put_timestamp=1;
firstchar=">";
v "will write timestamp and begin task";
;;
E) end_task=1
put_timestamp=1;
firstchar="<";
v "will end task and compute time difference";
;;
O) append=0
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
# Although the message should be quoted, ideally, we'll take the remainder of the
# command line just in case the user forgot.
message="$@"
# if there is no message, we'll display the last few lines of the output file
if [ "$message" = "" ]; then
v "Listing last few lines of $output_file:";
v "===================================================";
tail "$output_file";
v "===================================================";
v "done.";
exit 0;
fi
# if we're ending a task, get the previous date when we were starting a task.
# then compute the number of seconds and divide by 3600 for an hour.minute
# value. This is added to the message.
if [ "$end_task" -eq "1" ]; then
v "Ending task and computing time difference...";
a=`awk "/>\t.+\t\t/" "$output_file" | tail -n 1 | cut -f 2`;
v "... task started at $a";
b=`date`;
v "... and ended at $b";
secsa=`date -j -f "%a %b %d %T %Z %Y" "$a" "+%s"`
v "... task started at $secsa seconds";
secsb=`date -j -f "%a %b %d %T %Z %Y" "$b" "+%s"`
v "... and ended at $secsb seconds";
message="$message; took: `echo \"scale=2; ($secsb-$secsa)/60/60\" | bc`"
fi
# beginning a task just adds a visual break
if [ "$begin_task" -eq "1" ]; then
write_to_file "\n"
fi
# generate the message, along with the first character and timestamp if desired.
if [ "$put_timestamp" -eq "1" ]; then
write_to_file "$firstchar\t`date`\t\t$message"
else
write_to_file "$firstchar\t\t\t$message"
fi
# done.
v "done."
# End of file
@kerrishotts
Copy link
Author

Notes

By default the script will write to ./my-notes.txt. If you don't want that to be the default file, edit the script appropriately, or use the -f switch.

Examples

With the default file:

note -B "Started working on feature A"     # begin a task
note -t "This note has a timestamp"        # add an entry with a timestamp
note "This note doesn't"                   # add an entry without a timestamp
note -E "Finished working on feature A"    # and end the task, computing the time difference
note                                       # display the recent notes

Specifying files:

note -f ~/global_notes.txt -B "Start Project"
note -f ~/global_notes.txt -t "Add a timestamp"
note -f ~/global_notes.txt "And one without"
note -f ~/global_notes.txt -E "End project"
note -f ~/global_notes.txt

Additional switches

  • v Turn on verbose mode
  • V display the version
  • h display help
  • ? display help
  • O overwrite the target file

Dependencies

This script relies on date, bc, test, awk, tail and cut.

My environment is Mac OS X 10.10 (Yosemite).

Legal

You can do whatever you like with this script; I'm releasing it under the MIT license.

While this script works on my machine, I assume no risk for your use, misuse, or abuse. Always verify scripts before adding them to your environment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment