Erweiterung der Schalenstrebe von rechts nach links

9

Wenn ich in zsh (und anderen Shells) ein Argument wie (zum Beispiel) einfüge:

{a,b,c}{d,e,f}

Klammererweiterung macht es in:

ad ae af bd be bf cd ce cf

Für meine Zwecke ist die Reihenfolge der Argumente wichtig, und ich brauche die geschweiften Klammern, um von rechts nach links anstatt von links nach rechts zu expandieren. Das heißt, ich möchte, dass die Erweiterung:

ad bd cd ae be ce af bf cf

Gibt es eine Möglichkeit, die Reihenfolge zu steuern, in der mehrere Sätze von Klammern erweitert werden? Ich suche etwas, das in jeder Situation funktioniert, nicht nur mit diesen Argumenten.

Michael Mrozek
quelle
Ich nehme an, Sie interessieren sich nicht für komplexere Lösungen mit Schleifen oder sortierter Ausgabe, oder?
Terdon
@terdon Wenn es keinen anderen Weg gibt, nehme ich an; Ich hatte gehofft, dass es einen Trick gibt, um die Reihenfolge der Bewertung der Zahnspangenerweiterung zu ändern, aber wahrscheinlich gibt es keinen. Diese Argumente waren jedoch nur ein Beispiel, daher ist etwas, für das nur funktioniert, {a,b,c}{d,e,f}nicht sehr hilfreich
Michael Mrozek
Ja, das habe ich mir gedacht. Möglicherweise möchten Sie dies jedoch klarstellen, um Antworten zu vermeiden, die auf der Sortierreihenfolge basieren.
Terdon
Siehe auch So
erstellen Sie

Antworten:

8

Sie können die Parametererweiterung mit der Klammererweiterung kombinieren.

% foo=(d e f)
$ echo {a,b,c}${^foo}
ad bd cd ae be ce af bf cf

Wenn Sie nicht fooseparat definieren möchten (wie es wahrscheinlich erscheint), können Sie Folgendes verwenden:

$ echo {a,b,c}${^:-d e f}
ad bd cd ae be ce af bf cf

Wenn Sie die rcexpandparamOption festgelegt haben, benötigen Sie die ^in beiden Beispielen nicht, um dieses Verhalten zu aktivieren.

(Hinweis: Während des Testens hatte ich auch die shwordsplitOption festgelegt. Wenn Sie sie nicht festgelegt haben, versuchen Sie es beispielsweise echo {a,b,c}${^=:-d e f}. Moral der Geschichte: In fast ist alles möglich zsh, aber Sie müssen sicherstellen, dass Sie die richtige verwenden Kombination von Optionen und Syntax.)

chepner
quelle
1
Sie sollten print -- {a,b,c}${^=:-d e f}als Hauptbeispiel verwenden, da wann split+globstandardmäßig in deaktiviert wurde zsh.
Cuonglm
4

In können zshSie das -C angegebene Argument für die Anzahl der Spalten verwenden, um Folgendes zu printmögen:

print $(print -C3 {a,b,c}{d,e,f})

...bekommen...

ad bd cd ae be ce af bf cf

... ohne die $IFSAufteilung wie folgt:

print -C3 {a,b,c}{d,e,f}

... druckt ...

ad bd cd
ae be ce
af bf cf

... aber du kannst das vorher machen wie ...

print -aC3 {a,b,c}{d,e,f}

ad ae af
bd be bf
cd ce cf

...oder...

print $(print -aC2 {foo,bar}{bad,baz})

foobad foobaz barbad barbaz
mikeserv
quelle
Das erzeugt die gleiche Ausgabe, die MIchael zu vermeiden versucht. Er will 1.1 2.1 3.1 und Sie geben 1.1 1.2 1.3 (wenn das klar ist).
Terdon
@terdon - guter Punkt.
Mikeserv
Ich vermute (obwohl nicht ausdrücklich angegeben), dass Michael nach der spezifischen Reihenfolge der Paarung ist. Ihr Ansatz funktioniert nur, wenn die Elemente alphabetisch sortiert werden können. Was ist mit foobad foobaz barbad barbaz{foo, bar} {bad, baz} `?
Terdon
@terdon - na ja, wenn er danach sucht, warum nicht? und trotzdem können die Spalten auf jede Art und Weise gepaart werden, wenn Sie rechnen.
Mikeserv
1
@terdon - Sie Moderatoren scheinen es sich zur Gewohnheit zu machen, zu sagen, was Sie nicht meinen.
Mikeserv
2

Sie können am Ende jedes Elements des zweiten Satzes eine Zahl einfügen und dann nach dem letzten Zeichen sortieren:

echo -e "\n"{a,b,c}{d1,e2,f3} | sort -k 1.3 | cut -c 1-2 | tr '\n' ' '

Noch besser wäre es, nach einem Trennzeichen (Leerzeichen) Zahlen hinzuzufügen, um Felder und keine Zeichen auszuschneiden:

echo -e "\n"{a,b,c}{"d 1","e 2","f 3"} | sort -k 2n | cut -f 1 -d ' ' -s | tr '\n' ' '
jimmij
quelle