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\1
would result in aInvalid back reference
error) – steeldriver Jul 10 '20 at 22:30sort -u
doesn't actually change the piped input tosed
at all. Compare the output ofprintf "%s\n" {1,2,3}{1,2,3}{1,2,3} | sort -u
with 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