1

I have a phrase like this:

The quick brown $UNKNOWN1 jumps over the $UNKNOWN2 dog

And I have a worldlist like this:

me
black
lazy
swan
dog
word
sky
fox
nothing
you

How can I permute the list in bash to have all the permutations like:

The quick brown you jumps over the nothing dog

The quick brown fox jumps over the lazy dog

and so on, all permutations. I tried with some for loops but got stuck because I think i need some loop inside a loop (nested loop). Something like:

for i in `cat wordlist.txt`;
  do echo "The quick brown $i jumps over the $UNKNOWN2 dog";
done

EDIT:

I think this is it:

#!/bin/bash

for i in `cat wordlist.txt`
  do
    for a in `cat wordlist.txt`
      do
        echo "The quick brown $i jumps over the $a dog"
    done
done
bsteo
  • 1,738
  • 6
  • 34
  • 60

3 Answers3

5

Just for fun, GNU Parallel is good at permutations too:

parallel echo The quick brown {1} jumps over the {2} dog :::: wordlist.txt :::: wordlist.txt

Or, the same, but omitting lines where the two words are the same:

parallel 'bash -c "[ {1} != {2} ] && echo The quick brown {1} jumps over the {2} dog"' :::: wordlist.txt wordlist.txt
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
1

I think i need some loop inside a loop.

You're right:

for i in $(cat wordlist.txt)
do
  for j in $(cat wordlist.txt)
  do
    echo "The quick brown $i jumps over the $j dog"
  done
done

You can optionally avoid it when $i = $j:

for i in $(cat wordlist.txt); do
  for j in $(cat wordlist.txt); do
    if [ "$i" != "$j" ]; then
      echo "The quick brown $i jumps over the $j dog"
    fi
  done
done
iBug
  • 35,554
  • 7
  • 89
  • 134
1

There is also a hacky alternative with no loops:

printf "The quick brown %s jumps over the %s dog.\n" $(join -j 2 words words)

In this case, join creates the cartesian product of the word list with itself. The result is a list of words. Each of these words is passed as an argument to printf.
printf prints the sentence, replacing %s with the next word from the list. After printing the sentence once, it still has unread words and continues until all words are printed.

Benefits:

  • Shorter program
  • Faster than loops

Drawbacks (exactly the same as for for i in $(cat wordlist))

  • May fail on long word lists due to max. number of arguments.
  • If the word list contains * or ? these might be expanded by bash.
  • Words from the word list have to be real words, whitespace is not allowed.
Socowi
  • 25,550
  • 3
  • 32
  • 54