开发者

Filtering output of permutations using bash

I am really a Newbie in bash programing and I need to perform a permutation, which I did using one post from this forum as follow Generating permutations using bash.

#!/bin/bash
    list=`echo {1..12}`
       for c1 in $list
       do
            for c2 in $list
            do
                 for c3 in $list
                 do
               开发者_运维百科     echo $c1-$c2-$c3
                 done
            done
       done

The output is

1-1-1

1-1-2

1-1-3 ...

but I do not want to have a number repeated in the line (1-1-1). Meaning if the number 1 is in the first position, I do not want it neither in the second nor in the third. like this

1-2-3

1-2-4

1-2-5

...

Can anybody help me? any hint is welcome.


I think you need to change your echo line to:

[ $c1 -ne $c2 -a $c1 -ne $c3 -a $c2 -ne $c3 ] && echo $c1-$c2-$c3


The link at the top of your question already includes a nice answer on how to do permutations in bash. But I think that's not the answer you're looking for so I suggest you to use the following script:

#!/bin/bash
list=`echo {1..12}`
for c1 in $list
do
    for c2 in $list
    do
        if [ "$c1" != "$c2" ]; then
            for c3 in $list
            do
                if [ "$c1" != "$c3" ]; then
                    echo $c1-$c2-$c3
                fi
            done
        fi
    done
done


Does this do what you're looking for?

#!/bin/bash
list=$(echo {1..12})
for c1 in $list
do
    for c2 in $list
    do
        if (( c2 != c1 ))
        then
            for c3 in $list
            do
                if (( c3 != c2 && c3 != c1))
                then
                    echo $c1-$c2-$c3
                fi
            done
        fi
    done
done

Partial output:

1-2-3
1-2-4
1-2-5
1-2-6
1-2-7
1-2-8
1-2-9
1-2-10
1-2-11
1-2-12
1-3-2
1-3-4
...
12-10-8
12-10-9
12-10-11
12-11-1
12-11-2
12-11-3
12-11-4
12-11-5
12-11-6
12-11-7
12-11-8
12-11-9
12-11-10


The solution in the questions gives a Cartesian product. The following function generates the permutations of a set of values.

declare -a set=( 1 2 3 )               # set to permute
declare -i n=${#set[@]}

permute ()
{
  declare -i  k=$1
  declare -i  i
  declare -i  save
  if [ $k -lt $((n-1)) ] ; then
    for (( i=k; i<n; i+=1 )); do
      save=${set[k]}                  # exchange elements
      set[k]=${set[i]}
      set[i]=$save
      permute $((k+1))                # recurse
      save=${set[k]}                  # exchange elements
      set[k]=${set[i]}
      set[i]=$save
    done
  else
    (IFS='-'; echo -e "${set[*]}")
  fi
} # ----------  end of function permute  ----------

permute 0

The output:

1-2-3
1-3-2
2-1-3
2-3-1
3-2-1
3-1-2


I was having a similar problem but with text characters, so, just in case it may help:

for i in {a..z} ; do for b in {a..z} ; do [[ ! "$i" == "$b" ]] && echo -e "$i $b" | xargs -n 1 |  sort | xargs ; done ; done | sort -u 

It will permutate a to z with a to z, not only not repeating characters, "a a", but also without redundancies such as "ab" and "ba", echoing just "ab", thanks to the "inline sorting" of elements (xargs | sort | xargs) followed by the final "sort -u" (or "uniq").

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜