I was doing research on how to generate all non-repeating permutations of a set of a numbers without using recursion in Bash and I found this answer that worked, but I want to understand why.
Say you have three numbers: 1, 2, 3.
The following command will generate all possible non-repeating permutations:
printf "%s\n" {1,2,3}{1,2,3}{1,2,3} | sort -u | sed '/\(.\).*\1/d'
123
132
213
231
312
321
I understand what the printf with %s does when the argument is the brace expansions of the set {1, 2, 3} three times (which would print every single possible outcome).
I know that sort -u will output only unique lines.
I know that sed /<pattern>/d is used to delete any lines that match <pattern>.
Reading the pattern within the sed, I am somewhat confused. I know how to read regex but I don't see how this pattern works within the sed command.
\( = literal '('
. = any character, once
\) = literal ')'
.* = any character, zero or more times
\1 = reference to first captured group
How does then the sed command remove non-unique values from this regex pattern? I don't understand how there's a reference to a captured group, when there's not really one? The parentheses are being used in the pattern to be matched literally? Everything about this execution makes sense to me until the sed command.
\(.\)is in fact a capture group (otherwise\1would result in aInvalid back referenceerror) – steeldriver Jul 10 '20 at 22:30sort -udoesn't actually change the piped input tosedat all. Compare the output ofprintf "%s\n" {1,2,3}{1,2,3}{1,2,3} | sort -uwith the output of justprintf "%s\n" {1,2,3}{1,2,3}{1,2,3}The outputs are exactly the same (at least on OSX). – Greenonline Jul 11 '20 at 17:11