How to generate a password from a number of randomly chosen words on linux

In the following example "/usr/share/dict/words" is a word list and "-n 4" specifies that 4 words are needed:
egrep "^[a-pr-xA-PR-X]{3,}\$" /usr/share/dict/words | egrep -v "[sS]\$" | tr "A-Z" "a-z" | sort | uniq | shuf -n 4 | sed -rn "s/^(.)(.*)/\\U\\1\\L\\2/;H;\${x;s/\\n/./g;s/^.(.*)/\\1/;p}"

Here's a short explanation for each command:
  1. The first regular expression (^[a-pr-xA-PR-X]{3,}$):
    • removes words from the word list that contain a Q, Z or Y character. "Q"s can be easily mistaken for "O"s, and the place of Z/Y characters are keyboard layout dependant in some languages (eg. in Hungarian), thus they are better avoided in passwords.
    • removes words with 1-2 characters
  2. The "[sS]$" regular expression makes sure that the words do not end with an "s", thus if the word list contains possessive "'s" (eg. "John's") or plurals (eg. "swords"), then those are not considered (obviously this will throw out a bunch of other words as well).
  3. Converting the word list to all lowercase letters (and sorting and deleting duplicates) makes sure that words present with both lowercase and capitalized forms are not picked with a higher chance.
  4. The shuf -n 4 command picks 4 lines/words randomly.
  5. The last sed command capitalizes the selected words and joins them together into a single phrase.
Of course, you can preprocess your word list with everything that comes before the "shuf" command, but this will not speed things up significantly ... unless you use this commandline very often (like once every second or so Smile ).