# How to find the number of unordered pairs from a list

I want to count the number of unordered pairs from a list.

In other words, I have a list:

``````ab
ba
ac
bc
``````

and I want to display:

``````2 ab
1 ac
1 bc
``````
• How did you come up with those numbers? You mean the letters themselves should be sorted on their own line, then the number of those sequences are counted up? ("ba" -> "ab" to make 2 "ab") – Jeff Schaller Aug 1 '17 at 10:56
• @user112 What about if you had another `bc` in your input list which will two `bc`s and not in wrong order, the count should be 2 or 1? and what if three `bc`s and one `cb`, what the count should be? 4? – αғsнιη Aug 1 '17 at 11:28

It sounds like a good job for `perl`:

``````perl -F -lane '\$count{join "", sort @F}++;
END{print "\$count{\$_} \$_" for sort keys %count}' < your-file
``````

With `gawk`:

``````gawk -F '' '{ print (\$1 > \$2) ? \$2\$1 : \$1\$2 }' | sort | uniq -c
``````

Each field matches one character (`-F ''`). We just invert the characters if the first is greater than the second according to the current locale (which does not matter). Then we sort the result and count the identical consecutive lines with `uniq -c`.

``````gawk -i join '
{
split(\$0, F, //)
asort(F)
h[join(F, 1, length(F), SUBSEP)]++
}
END {
asorti(h, x)
for(k in h)
print h[k], k
}' infile
``````

Or as a separate script:

order.awk

``````@include "join"
{
split(\$0, F, //)
asort(F)
h[join(F, 1, length(F), SUBSEP)]++
}
END {
asorti(h, x)
for(k in h)
print h[k], k
}
``````

Run it like this:

``````gawk -f order.awk infile
``````

Output:

``````2 ab
1 ac
1 bc
``````

`fish` shell:

``````⋊> ~ echo 'ab
ba
ac
bc' | while read line; echo -n "\$line" | sed -r 's|(.)|\1\n|g' | sort | xargs | tr --delete ' '; end | uniq -c
``````

`bash` shell:

``````bash-3.2\$ echo 'ab
ba
ac
bc' | while read line; do echo -n "\$line" | sed -r 's|(.)|\1\n|g' | sort | xargs | tr --delete ' '; done | uniq -c
``````

Output:

``````     2 ab
1 ac
1 bc
``````