Drew Scott Daniels' Blog Personal, usually technical posts

March 20, 2010

Random word’s definition shell script

Filed under: Uncategorized — admin @ 9:16 pm

dict "$(head -n $(($(od -N 2 /dev/urandom|cut -d' ' -f2 -s)%98326)) /usr/share/dict/british-english| tail -n1)" |less

More people may prefer:

dict "$(head -n $(($(od -N 2 /dev/urandom|cut -d' ' -f2 -s)%$(wc -l /usr/share/dict/words|cut -d' ' -f1))) /usr/share/dict/words| tail -n1)"|more

  • I still want to check for bashisms
  • 98326 is the output of wc -l /usr/share/dict/british-english. I put it inline for speed, and didn’t bother with a variable since I wanted a one line script.
  • If the dictionary is too big then a larger random number would be needed.
  • /usr/share/dict/british-english isn’t installed on many systems, but words is.
  • “more” is lighter weight than “less”, and is installed on more systems. It lacks the ability to go backwards.

To get a random number I used:

$(od -N 2 /dev/urandom|cut -d' ' -f2 -s)

  • od converts to decimal.
  • -N 2 gets two bytes
  • /dev/urandom is pseudorandom bytes from the kernel. There might be a more cross platform alternative like maybe $RANDOM for bash.
  • cut -d' ' -f2 -s gets only the second column. Often awk '{print $2}' is used instead. Awk can be very big. gawk is said to be big, and mawk is said to be minimal. cut seems more portable and smaller yet to me. -d sets the delimiter, -f2 is field two, -s is only print lines with the delimiter.

Try “set -x” before the command to see the different levels of shell script in the one line, do “set +x” after to get things back to normal.

Drew Daniels’ resume: http://www.boxheap.net/ddaniels/resume.html

Powered by WordPress