Basic Combination Shell Script

I need to have a script read a file that has a list of words in a single column like below:

Black
Blue
Brown
Orange
Red
Yellow
Green
White
Purple
Silver
Grey
Tan

Then print to another file just all of the two-word possible combinations. Example:

Black,Blue

Anyone want to take a crack at this?

Using bash:

#!/bin/bash
while read word
do
  S[${#S[@]}]="$word"
done < infile

for ((x=0;x<${#S[@]};x++))
do
   for ((y=x+1;y<${#S[@]};y++))
   do
         echo "${S[x]},${S[y]}"
   done
done > outfile

Using awk:

awk '{S[NR]=$0}
END {
   for(x=1;S[x];x++)
      for(y=x+1;S[y];y++)
         print S[x]","S[y]
}' infile

Hi.

Also a script with a utility written in perl :

#!/usr/bin/env bash

# @(#) s1       Demonstrate combinations of 2 from list of strings in file.

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
em() { pe "$*" >&2 ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C combination my-columns head tail

FILE=${1-data1}

pl " Input data file $FILE, columnized:"
my-columns $FILE

pl " Results:"
combination 2 $( cat $FILE ) |
tee f1 |
head -3
pe "..."
tail -3 f1

exit 0

producing:

$ ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.4 (jessie) 
bash GNU bash 4.3.30
combination (local) 1.1
my-columns (local) 1.3
head (GNU coreutils) 8.23
tail (GNU coreutils) 8.23

-----
 Input data file data1, columnized:
Black Blue Brown Orange Red Yellow Green White Purple Silver Grey Tan

-----
 Results:
Black Blue
Black Brown
Black Orange
...
Silver Grey
Silver Tan
Grey Tan

Eliminating the niceties from the perl code leaves the heart of the utility like this:

perl -w -e '
BEGIN { @a = @ARGV }
use Math::Combinatorics;
print join( "\n", map { join " ", @$_ } combine( 2, @a ) ),
"\n";' $( cat $FILE )

Best wishes ... cheers, drl

I don't know if it's really out of purpose , but you 'll get such result using a single table in SQL.
This is a complete demo using sqlite ( sqllite3 under CYGWIN on my Windows PC

This code is limited to 4 items , just to avoid useless lines of results .

$ sqlite3
SQLite version 3.14.1 2016-08-11 18:53:32
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> create table colors (name text ) ;
sqlite> insert into colors values ("Black");
sqlite> insert into colors values ("Blue");
sqlite> insert into colors values ("Brown");
sqlite> insert into colors values ("Orange");
sqlite> select * from colors ;
Black
Blue
Brown
Orange

sqlite> select a.name,b.name from colors a,colors b ;
Black|Black
Black|Blue
Black|Brown
Black|Orange
Blue|Black
Blue|Blue
Blue|Brown
Blue|Orange
Brown|Black
Brown|Blue
Brown|Brown
Brown|Orange
Orange|Black
Orange|Blue
Orange|Brown
Orange|Orange

sqlite>

This is so called a Cartesian product.

awk '{
	Arr[i++]=$0
	}
	END{
	for(j=0;j<=i;j++)
	{
		for(k=j+1;k<i;k++)
		{
			print Arr[j],Arr[k]
		}
	}
}' input_file