ubuntuusers.de

Alle möglichen Kombinationen als Liste ausgeben

Status: Gelöst | Ubuntu-Version: Kubuntu 19.04 (Disco Dingo)
Antworten |

joma1234

Anmeldungsdatum:
2. Juli 2019

Beiträge: 10

Hallo miteinander,

ich habe 3 Switches:

S1
S2
S3

Jedes kann auf "on" oder auf "off" stehen. Jetzt hätte ich gerne eine Liste alle möglichen Kombinationen, ohne Berücksichtigung auf Reihenfolge und es sollten keine doppelten Einträge erscheinen. Ich würde so etwas erwarten:

S1_on S2_on S3_on
S1_on S2_off S3_on
S1_on S2_on S3_off
S1_on S2_off S3_off
...

Ich habe es schon mit 'echo {S1_on,S1_off} {S2_on,S2_off} {S3_on,S3_off}' ausprobiert, aber es ist nicht ganz was ich will. kennt ihr eine bessere Lösung, idealerweise ein Einzeiler, aber eine kleines Mini-Script wäre auch toll.

Danke schon mal!

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11271

Wohnort: München

Mit Python3 könnte man das unter Nutzung der itertools z.B. so machen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/usr/bin/env python3
import itertools
import sys

names = sys.argv[1:]
states = list(f"{name}_{state}" for name, state
              in itertools.product(names, ('on', 'off')))
grouped_states = zip(states[0::2], states[1::2])

for p in itertools.product(*grouped_states):
    print(*p)

Das Skript erwartet die an-/abschaltbaren Elemente als Argumente - für den Fall mit drei Argumenten:

$ ./get_states S1 S2 S3
S1_on S2_on S3_on
S1_on S2_on S3_off
S1_on S2_off S3_on
S1_on S2_off S3_off
S1_off S2_on S3_on
S1_off S2_on S3_off
S1_off S2_off S3_on
S1_off S2_off S3_off 

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11271

Wohnort: München

Oder noch generischer, wenn man mehr als zwei Schaltzustände braucht:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python3
import argparse
import itertools

parser = argparse.ArgumentParser(description="print product of states for switches")
parser.add_argument('switches', metavar='SWITCH', nargs='+',
                    help="names of the switches")
parser.add_argument('--state', '-s', metavar='STATE', action='append',
                    help="add possible state")
args = parser.parse_args()

switches = args.switches
states = args.state
grouped_states = ((f"{sw}_{st}" for sw, st in itertools.product((switch,), states))
                  for switch in switches)

for p in itertools.product(*grouped_states):
    print(*p)
$ ./get_states -s on -s off S1 S2 S3
S1_on S2_on S3_on
S1_on S2_on S3_off
S1_on S2_off S3_on
S1_on S2_off S3_off
S1_off S2_on S3_on
S1_off S2_on S3_off
S1_off S2_off S3_on
S1_off S2_off S3_off

$ ./get_states S1 S2 S3 S4 -s full -s half -s off
S1_full S2_full S3_full S4_full
S1_full S2_full S3_full S4_half
S1_full S2_full S3_full S4_off
S1_full S2_full S3_half S4_full
S1_full S2_full S3_half S4_half
S1_full S2_full S3_half S4_off
S1_full S2_full S3_off S4_full
S1_full S2_full S3_off S4_half
S1_full S2_full S3_off S4_off
S1_full S2_half S3_full S4_full
S1_full S2_half S3_full S4_half
S1_full S2_half S3_full S4_off
S1_full S2_half S3_half S4_full
S1_full S2_half S3_half S4_half
S1_full S2_half S3_half S4_off
S1_full S2_half S3_off S4_full
S1_full S2_half S3_off S4_half
S1_full S2_half S3_off S4_off
S1_full S2_off S3_full S4_full
S1_full S2_off S3_full S4_half
S1_full S2_off S3_full S4_off
S1_full S2_off S3_half S4_full
S1_full S2_off S3_half S4_half
S1_full S2_off S3_half S4_off
S1_full S2_off S3_off S4_full
S1_full S2_off S3_off S4_half
S1_full S2_off S3_off S4_off
S1_half S2_full S3_full S4_full
S1_half S2_full S3_full S4_half
S1_half S2_full S3_full S4_off
S1_half S2_full S3_half S4_full
S1_half S2_full S3_half S4_half
S1_half S2_full S3_half S4_off
S1_half S2_full S3_off S4_full
S1_half S2_full S3_off S4_half
S1_half S2_full S3_off S4_off
S1_half S2_half S3_full S4_full
S1_half S2_half S3_full S4_half
S1_half S2_half S3_full S4_off
S1_half S2_half S3_half S4_full
S1_half S2_half S3_half S4_half
S1_half S2_half S3_half S4_off
S1_half S2_half S3_off S4_full
S1_half S2_half S3_off S4_half
S1_half S2_half S3_off S4_off
S1_half S2_off S3_full S4_full
S1_half S2_off S3_full S4_half
S1_half S2_off S3_full S4_off
S1_half S2_off S3_half S4_full
S1_half S2_off S3_half S4_half
S1_half S2_off S3_half S4_off
S1_half S2_off S3_off S4_full
S1_half S2_off S3_off S4_half
S1_half S2_off S3_off S4_off
S1_off S2_full S3_full S4_full
S1_off S2_full S3_full S4_half
S1_off S2_full S3_full S4_off
S1_off S2_full S3_half S4_full
S1_off S2_full S3_half S4_half
S1_off S2_full S3_half S4_off
S1_off S2_full S3_off S4_full
S1_off S2_full S3_off S4_half
S1_off S2_full S3_off S4_off
S1_off S2_half S3_full S4_full
S1_off S2_half S3_full S4_half
S1_off S2_half S3_full S4_off
S1_off S2_half S3_half S4_full
S1_off S2_half S3_half S4_half
S1_off S2_half S3_half S4_off
S1_off S2_half S3_off S4_full
S1_off S2_half S3_off S4_half
S1_off S2_half S3_off S4_off
S1_off S2_off S3_full S4_full
S1_off S2_off S3_full S4_half
S1_off S2_off S3_full S4_off
S1_off S2_off S3_half S4_full
S1_off S2_off S3_half S4_half
S1_off S2_off S3_half S4_off
S1_off S2_off S3_off S4_full
S1_off S2_off S3_off S4_half
S1_off S2_off S3_off S4_off 

joma1234

(Themenstarter)

Anmeldungsdatum:
2. Juli 2019

Beiträge: 10

Hallo miteinander,

ich hab 3 Switche:

S1
S2
S3

Und jeder dieser switche kann "1" oder "0" sein. Jetzt würde ich gerne eine Auflistung aller Kombinationen bekommen, wobei keine mehrfach aufgelistet werden soll, noch die Reihenfolge wichtig wäre. Ich würde folgendes Ergebniss gerne bekommen:

S1_1 S2_1 S2_1 
S1_1 S2_0 S2_1 
S1_1 S2_1 S2_0 
S1_1 S2_0 S2_0 

S1_0 S2_1 S2_1 
S1_0 S2_0 S2_1 
S1_0 S2_1 S2_0 
S1_0 S2_0 S2_0

Wie könnte ich das erreichen? Am liebsten wäre mir ein Einzeiler, aber ein Mini-Skript wäre auch nicht schlimm.

Vielen Dank schon mal!

Moderiert von ChickenLipsRfun2eat:

Das Thema ist mit diesem zusammengeführt worden. Bitte erstelle nur ein Thema pro Fragestellung!

dingsbums

Anmeldungsdatum:
13. November 2010

Beiträge: 3791

1
2
3
4
5
6
7
8
9
for var1 in {0..1};do for var2 in {0..1};do for var3 in {0..1};do echo "S1_$var1 S2_$var2 S3_$var3";done;done;done
S1_0 S2_0 S3_0
S1_0 S2_0 S3_1
S1_0 S2_1 S3_0
S1_0 S2_1 S3_1
S1_1 S2_0 S3_0
S1_1 S2_0 S3_1
S1_1 S2_1 S3_0
S1_1 S2_1 S3_1

dingsbums

Anmeldungsdatum:
13. November 2010

Beiträge: 3791

Na, das war wohl eine dringliche Hausaufgabe, wenn man dafür 2 Threads erstellen muss. Siehe https://forum.ubuntuusers.de/topic/alle-moeglichen-kombinationen-als-liste-ausgeb/.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17625

Wohnort: Berlin

Zeilenumbruch erfordert ein "\n", und damit echo das akkurat umsetzt muss man diesem -e sagen, wie "ernsthaft", "echt":

1
echo -e S1_o{n,ff}" "S2_o{n,ff}" "S3_o{n,ff}"\n"

oder etwas hübscher:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
echo -e "\n"S1_o{n" ",ff}" "S2_o{n" ",ff}" "S3_o{n,ff}

S1_on  S2_on  S3_on 
S1_on  S2_on  S3_off 
S1_on  S2_off S3_on 
S1_on  S2_off S3_off 
S1_off S2_on  S3_on 
S1_off S2_on  S3_off 
S1_off S2_off S3_on 
S1_off S2_off S3_off

000 bis 111 ist ja, binär verstanden und dezimal gesehen 0 bis 4+2+1 = 7. Damit lässt sich sicher auch was basteln. ☺

Da wir uns oben aber so viel Arbeit gemacht haben wiederverwenden wir diese vielleicht lieber derart:

1
echo -e "\n"S1_o{n" ",ff}" "S2_o{n" ",ff}" "S3_o{n,ff} | sed 's/on/1/g;s/off/0 /g'

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13226

Man kann so etwas ganz gut mit Integern machen, die man als Bitset nutzt:

1
2
3
4
5
6
7
8
9
$ ./xx.rb 
S1_on S2_on S3_on
S1_off S2_on S3_on
S1_on S2_off S3_on
S1_off S2_off S3_on
S1_on S2_on S3_off
S1_off S2_on S3_off
S1_on S2_off S3_off
S1_off S2_off S3_off

Der Code:

1
2
3
4
5
#!/usr/bin/ruby

8.times do |x|
  puts 3.times.map {|i| "S#{i + 1}_#{x[i] == 0 ? "on" : "off"}"}.join(" ")
end

Edit: korrigiert

LinuxDee

Anmeldungsdatum:
15. Juli 2019

Beiträge: 11

Hallo user_unknown,

bin absolut nicht firm in Programmierung und habe auch so meine Schwierigkeiten Quelltexte zu lesen, versuche aber dennoch etwas mehr in Programmierung hinein zu kommen und lese deshalb oft in Quelltexten mit, wenn ich die Zeit und Ausdauer dazu habe. Dabei fand ich diesen Codeschnipsel von dir

echo -e "\n"S1_o{n" ",ff}" "S2_o{n" ",ff}" "S3_o{n,ff} | sed 's/on/1/g;s/off/0 /g'

wovon ich den ersten Teil bis zur Pipe ja noch nachvollziehen kann, aber 'sed' soll ja wohl etwas ersetzen und da verlässt es mich. Könntest du die Parameter noch kurz anreißen, vielleicht stehe ich auch zu sehr auf dem Schlauch und es bedarf nur eines kleinen Schubs in die richtige Richtung? Die Beispiele unter https://wiki.ubuntuusers.de/sed/ geben da nicht so wirklich etwas für mich her, insbesondere der Parameter 'g' interessiert mich da, denn auch die manpage erhellt mich da keineswegs..

Danke vielmals Detlev

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17625

Wohnort: Berlin

1
echo -e "\n"S1_o{n" ",ff}" "S2_o{n" ",ff}" "S3_o{n,ff} | sed 's/on/1/g;s/off/0 /g'

Das s-Kommando substituiert, also ersetzt:

1
2
echo "Banane"  | sed 's/a/o/'
Bonane

Ersetze a durch o - sed sucht und ersetzt das erste a durch o (pro Zeile) und ist dann fertig.

Will man alle a durch o ersetzen muss man als Schalter noch g für global verwenden:

1
2
echo "Banane"  | sed 's/a/o/g'
Bonone

Mehrere Befehle kann man durch Semikolon voneinander trennen:

1
2
echo "Banane"  | sed 's/e/as/; s/Ba/A/'
Ananas
Antworten |