Befehl bash column, der durch ANSI-Farb-Escapezeichen verwirrt ist

7

Ich habe ein Bash-Skript, das ich von Gary Bernhardts Dotfiles erhalten habe und das eine schöne kolorierte Liste der letzten Git-Commits druckt. Mit dem columnBefehl wird die Ausgabe in Spalten angeordnet. Auf meinem Mac funktioniert es wunderbar.

Seltsamerweise funktioniert das Spaltenbit jedoch nicht, wenn ich es unter Cygwin oder CentOS 6 ausführe. Alle Felder haben unabhängig von ihrer Länge drei Zwischenräume, wodurch gezackte Rinnen zwischen "Säulen" entstehen. Ich habe es auf die ANSI-Farb-Escape-Codes eingegrenzt. Wenn ich diese entferne, kommen die Säulen in einer Reihe heraus.

Die zsh-Version ist bei allen drei gleich (und das Problem tritt in bash genauso auf). Ich kann nicht sagen, was die Version von columnist, aber sie sehen genauso aus und ihre Manpages sind für alles, was es wert ist, gleich.

Warum sollte dies auf meinem Mac funktionieren, aber nicht auf den anderen Betriebssystemen?

scanny
quelle
Haben Sie die gleichen Escape-Codes in der OSX-Version?
Terdon
1
@terdon: Ja, es ist genau der gleiche Code auf allen Systemen; Es verwendet die Standard-ANSI-Farb-Escape-Sequenzen und die Farbe wird auf allen Systemen richtig ausgegeben. Nur die Ausrichtung ist unterschiedlich. Der Code ist hier: github.com/scanny/dotfiles/blob/master/link/.githelpers#L52 Eine seltsame Sache ist, dass die Escape-Codes an jeder Position in jeder Zeile genau gleich lang sind. Selbst wenn sie in die Anzahl der Charaktere einbezogen würden, würde dies die Ausrichtung nicht beeinträchtigen.
Scanny
1
Das gleiche Problem hier zu haben .. würde gerne dieses Protokollformat mit schönen Spalten haben, aber Bash mag es aus irgendeinem Grund nicht ...
Wulftone
vergessen zu erwähnen, ich bin auf Bogen mit Bash 4.2.045-5
Wulftone

Antworten:

1

columnarbeitet pro Charakter. Es zählt druckbare Zeichen von jeder Zelle und dann Pads , um sie auszurichten (siehe Codequellen für V2.29).

Das Problem besteht darin, dass Ihr Stream nicht druckbare ANSI-Escape-Sequenzen enthält, in die druckbare Zeichen eingebettet sind. columnDann kann die minimale Breite der realen Zelle dieser Zellen nicht berechnet werden und die nächsten Zellen derselben Zeile werden falsch ausgerichtet.


Hier ist ein Beispiel mit dem blauen Farbcode <esc>[34mfür die AZelle in Spalte v2.29:

$ echo '\033[34mA\033[0m B\nC D'|column -t
A  B
C         D

AZelle wird als höhenbedruckbares Zeichen angesehen, solange nur beide Escapezeichen als nicht druckbar erkannt werden. Daher erhält die C-Spalte sieben unerwünschte Auffüllräume.


Beachten Sie, dass dieses Verhalten in allen Spaltenversionen nicht konsistent ist. Version 2.26 wcswidthberechnet die sichtbare Breite der Zellen und führt zu einer anderen Fehlausrichtung.

A. Loiseau
quelle
Dies ist wirklich ein nützlicher Einblick @A. Gibt es in diesem Fall etwas zu tun, wie einen alternativen Befehl / Ansatz zu verwenden? oder ist es nur eine Grenze dessen, was mit dem, was die Befehlsshell zu bieten hat, getan werden kann?
Scanny
Ich kenne kein columnbefehlszeilenähnliches Tool, das verschiedene Escape-Sequenzen und andere Sonderzeichen kennt, aber es ist immer möglich, eines zu erstellen. Es ist möglicherweise nicht so einfach, die Zellenbreite einfach gut zu zählen. Beispielsweise muss ein solches Tool möglicherweise über Hintergrundfarbcodes Bescheid wissen, um sie zwischen Zellen zu beenden und erneut zu öffnen. Es muss auch Trennzeichen in diesen Sequenzen überspringen, um sie nicht zu ändern.
A. Loiseau
Eine Möglichkeit, Fehlausrichtungen zu umgehen, besteht darin, \010am Anfang jeder falsch ausgerichteten Zelle Rückräume einzufügen . Also siebenmal am Anfang der D-Zelle in meinem Beispiel : echo '\033[34mA\033[0m B\nC \010\010\010\010\010\010\010D'|column -t.
A. Loiseau
Beachten Sie, dass Sie in der Syntax des Git-Protokollformats Backslash folgendermaßen codieren können : %x08.
A. Loiseau
0

Möglicherweise columnprüft $TERMund / oder prüft der Befehl $LANG, was (wenn überhaupt) einen Farbcode ausmacht.

Natürlich können Sie auch zunächst git log --pretty=format:...ein spaltenausgerichtetes farbcodiertes Protokoll ausgeben. Zum Beispiel benutze git histund habe ich dies in meinem ~/.git/config:

[alias]
   hist = log --pretty=format:\"           \t%C(yellow)%h %C(red)%ad %C(cyan)%aN%C(reset)   \t| %s%C(blue)%d%C(reset)\" --graph --date=short
Martin
quelle