#!/bin/bash # Globals usage="Usage: ${0##*/} [-n] [-r repeat] databasedir" newlinebetween="false" oldifs="$IFS" repeat="1" aoran="0" upper="0" # Functions function parse_template { local object max word i if [[ -z "$1" ]]; then return; fi local IFS=" " for object in $1; do case "${object:0:1}" in \_) # Ignore spaces when doing an aoran if [[ "$aoran" -eq "0" ]]; then # Echo a space echo -n " " fi ;; \\) # Echo a newline echo ;; \|) # Echo an "a" or an "an", depending on the next raw word ((aoran++)) parse_template "${object:1}" ;; \^) # Capitalize the next letter ((upper++)) parse_template "${object:1}" ;; \() # Repeat the following n times number="${object:1}" number="${number%%)*}" while [[ "$i" -lt "$number" ]]; do parse_template "${object##*)}" ((i++)) done ;; \:) # Choose an entry from the object database and parse it as a template eval max=\$dbmax${object:1} if [[ -z "$max" ]]; then echo "Error, db object $object not found, aborting" exit 1 fi rand=$(($RANDOM % $max)) eval word=\${db${object:1}[\$rand]} parse_template "$word" ;; *) object=${object# } # Assume a raw word if [[ "$aoran" -gt "0" ]]; then ((aoran--)) if [[ "${object:0:1}" == [aeiou] ]]; then parse_template "an _" else parse_template "a _" fi fi if [[ "$upper" -gt "0" ]]; then ((upper--)) echo -n "${object:0:1}" | tr [a-z] [A-Z] parse_template "${object:1}" else echo -n "$object" fi ;; esac done } # Parse command line while [[ "${1:0:1}" == "-" ]]; do case "$1" in -n) newlinebetween="true"; shift; ;; -r) if [[ -z "$2" ]]; then echo "$usage" exit 1 fi repeat="$2" shift 2; ;; *) echo "$usage" exit 1 ;; esac done # Sanity check if [[ -z "$1" ]]; then echo $usage exit 1 fi # Load the wordlists and templates for file in "$1"/*; do basename=${file##*/} IFS=$'\n' if [[ "$basename" == "template" ]]; then dbmaxtemplate="0" for word in $(<"$file"); do dbtemplate[$dbmaxtemplate]=$word ((dbmaxtemplate++)) done else for word in $(<"$file"); do i=0 syl=0 dbname="$basename" while [[ "${word:$i:1}" == "+" ]]; do ((syl++)) ((i++)) done if [[ "$syl" != "0" ]]; then dbname="${dbname}${syl}"; fi if eval [[ -z dbmax${dbname} ]]; then eval dbmax${dbname}="0" fi eval db${dbname}[dbmax${dbname}]=\${word:i} ((dbmax${dbname}++)) done fi IFS="$oldifs" done # Sanity check, we need a template if [[ -z "$dbmaxtemplate" ]]; then echo "Template file not parsed, aborting" exit 1 fi while [[ "$repeat" -gt "0" ]]; do # Choose a random template template=$(($RANDOM % $dbmaxtemplate)) parse_template "${dbtemplate[$template]}" ((repeat--)) if [[ "$newlinebetween" == "true" && "$repeat" -gt "0" ]]; then echo fi done # Put a final newline echo