Ich versuche, zwei Zeichenfolgen zu drucken, die durch eine TAB getrennt sind. Ich habe versucht:
echo -e 'foo\tbar'
printf '%s\t%s\n' foo bar
Beide drucken:
foo bar
Wobei das Leerzeichen zwischen den beiden tatsächlich 5 Leerzeichen beträgt (gemäß Auswahl der Ausgabe mit der Maus in Putty).
Ich habe auch versucht, STRG + V zu verwenden und beim Eingeben des Befehls die Tabulatortaste zu drücken, mit dem gleichen Ergebnis.
Was ist der richtige Weg, um das Drucken von Registerkarten als Registerkarten zu erzwingen, damit ich die Ausgabe auswählen und mit Registerkarten an eine andere Stelle kopieren kann?
Und die zweite Frage: Warum erweitert Bash Tabulatoren in Leerzeichen?
Update : Anscheinend ist dies ein Problem von Putty: /superuser/656838/how-to-make-putty-display-tabs-within-a-file-instead-of-changing-them-to -spaces
quelle
printf '%s\\t%s\n' foo bar
foo\tbar
...$'\t'
als Tabulator. So können Sie Zeichenfolgen wie diese immer verketten - zum Beispiel als Zuordnung:v='This is'$'\t''a test'
Und das drucken Sie es buchstäblich, zBprintf '%s' "$v"
Antworten:
Wie ilkkachu sagte, ist dies kein Problem mit bash, sondern mit dem Terminalemulator, der Tabulatoren in Leerzeichen bei der Ausgabe konvertiert.
Wenn Sie verschiedene Terminals, Putty, Xterm und Konsole überprüfen, werden Registerkarten in Leerzeichen konvertiert, während dies bei urxvt und gnome-terminal nicht der Fall ist. Eine andere Lösung besteht darin, die Terminals zu wechseln.
quelle
stty tab3
.Nein, ist es nicht. Nicht in der Ausgabe von
echo
oderprintf
.Dies ist ein anderes Problem. Es geht nicht um die Shell, sondern um den Terminalemulator, der die Tabulatoren bei der Ausgabe in Leerzeichen konvertiert. Viele, aber nicht alle machen das.
Es ist möglicherweise einfacher, die Ausgabe mit Tabulatoren in eine Datei umzuleiten und von dort zu kopieren oder in
unexpand
der Ausgabe Leerzeichen in Tabulatoren zu konvertieren. (Obwohl es auch nicht wissen kann, mit welchem Leerzeichen Tabs anfänglich waren, wird es, wenn möglich, alles in Tabs konvertieren.) Dies hängt natürlich davon ab, was genau Sie mit der Ausgabe tun müssen.quelle
In
printf '%s\t%s\n' foo bar
,printf
gibt ausfoo<TAB>bar<LF>
.f
,o
,b
,a
Undr
sind einfach breite graphischen Zeichen.Nach Erhalt dieser Zeichen zeigt das Terminal eine entsprechende Glyphe an und bewegt den Cursor eine Spalte nach rechts, es sei denn, er hat bereits den rechten Bildschirmrand erreicht (Papier in Original-Fernschreibmaschinen). In diesem Fall wird möglicherweise eine Zeile eingezogen und kehren Sie zum linken Bildschirmrand zurück (Wrap) oder verwerfen Sie das Zeichen je nach Terminal und Konfiguration.
<Tab>
und<LF>
sind zwei Steuerzeichen .<LF>
(auch bekannt als newline) ist das Zeilentrennzeichen in Unix-Text, aber bei Terminals wird nur eine Zeile eingezogen (bewegen Sie den Cursor eine Position nach unten). Der Terminaltreiber im Kernel übersetzt ihn also tatsächlich in<CR>
(Rückkehr zum linken Bildschirmrand)<LF>
(Cursor nach unten) (stty onlcr
normalerweise standardmäßig aktiviert).<Tab>
Weist das Terminal an, den Cursor zum nächsten Tabulator zu bewegen (der bei den meisten Terminals standardmäßig 8 Positionen voneinander entfernt ist, aber auch so konfiguriert werden kann, dass er überall eingestellt werden kann), ohne die Lücke mit Leerzeichen zu füllen.Wenn diese Zeichen also alle 8 Spalten an ein Terminal mit Tabulatoren gesendet werden, während sich der Cursor am Anfang einer leeren Zeile befindet, führt dies zu:
in dieser Zeile auf dem Bildschirm gedruckt. Wenn sie gesendet werden, während sich der Cursor an dritter Stelle in einer Zeile befindet
xxxxyyyyzzzz
, die Folgendes enthält , führt dies zu:Auf Terminals, die keine Tabellierung unterstützen, kann der Terminaltreiber so konfiguriert werden, dass diese Registerkarten in Leerzeichenfolgen übersetzt werden. (
stty tab3
).Das SPC-Zeichen in Original-Fernschreibmaschinen würde den Cursor nach rechts bewegen, während die Rücktaste (
\b
) ihn nach links bewegen würde. In modernen Terminals bewegt sich SPC nach rechts und löscht auch (schreibt ein Leerzeichen, wie Sie es erwarten würden). Der Anhänger von\b
musste also etwas Neueres als ASCII sein. Auf den meisten modernen Terminals, es ist eigentlich eine Folge von Zeichen:<Esc>
,[
,C
.Es gibt mehr Escape-Sequenzen, um
n
Zeichen nach links, rechts, oben, unten oder an einer beliebigen Position auf dem Bildschirm zu bewegen . Es gibt andere Escape-Sequenzen, um Teile von Linien oder Bereichen des Bildschirms usw. zu löschen (mit Leerzeichen zu füllen).Diese Sequenzen werden in der Regel durch visuelle Anwendungen wie
vi
,lynx
,mutt
,dialog
wo Text an beliebigen Positionen auf dem Bildschirm geschrieben wird.Mit allen X11-Terminalemulatoren und einigen anderen Nicht-X11-Emulatoren wie GNU können
screen
Sie jetzt Bereiche des Bildschirms zum Kopieren und Einfügen auswählen. Wenn Sie einen Teil dessen auswählen, was Sie imvi
Editor sehen, möchten Sie nicht alle Escape-Sequenzen kopieren, die zur Erstellung dieser Ausgabe verwendet wurden. Sie möchten den dort angezeigten Text auswählen.Zum Beispiel, wenn Sie ausführen:
Welche einen Editor Sitzung simuliert , wo Sie eingeben
abC
, gehen Sie an den Anfang zurück, ersetzenab
mitAC
,C
mitB
, Umzug in den nächsten Tabstopp, dann eine weitere Spalte nach rechts, dann zwei Spalten nach links, dann eingebenD
.Sie sehen:
Das heißt,
ABC
eine Lücke von 4 Spalten undD
.Wenn Sie dies mit der Maus in
xterm
oder auswählen,putty
werden in der AuswahlABC
4 Leerzeichen undD
nicht gespeichertabC<CR>AC<BS>B<Tab><Esc>[C<BS><BS>D
.Was in der Auswahl endet, ist das, was
printf
sowohl vom Terminaltreiber als auch vom Terminalemulator gesendet, aber nachbearbeitet wurde.Für andere Arten der Transformation siehe die
<U+0065><U+0301>
(e
gefolgt von einem kombinierten akuten Akzent) geändert in<U+00E9>
(é
die vorkomponierte Form) durchxterm
.Oder
echo abc
das wirdABC
vom Terminaltreiber übersetzt, bevor es nach a an das Terminal gesendet wirdstty olcuc
.Nun,
<Tab>
wie<LF>
ist eines dieser wenigen Steuerzeichen, die tatsächlich manchmal in Textdateien gefunden werden (auch<CR>
in MSDOS-Textdateien und manchmal<FF>
für Seitenumbrüche).Einige Terminalemulatoren kopieren sie daher nach Möglichkeit in die Puffer zum Kopieren und Einfügen, um sie zu erhalten (dies ist jedoch im Allgemeinen weder der Fall
<CR>
noch der Fall<LF>
).In VTE-basierten Terminals wie
gnome-terminal
können Sie beispielsweise feststellen, dass bei Auswahl des Ausgangsprintf 'a\tb\n'
in einer leeren Zeilegnome-terminal
tatsächlich 7 Leerzeichen unda\tb
in der X11-Auswahla
gespeichert werdenb
.Aber für die Ausgabe
printf 'a\t\bb\n'
, es speicherta
, 6 Räume undb
, und fürprintf 'a\r\tb\n'
,a
, 7 Räume undb
.Es gibt andere Fälle, in denen die Terminals versuchen, die tatsächliche Eingabe zu kopieren, z. B. wenn Sie nach dem Ausführen zwei Zeilen auswählen, in
printf 'a \nb\n'
denen dieser unsichtbare nachfolgende Speicherplatz erhalten bleibt. Oder wenn Sie zwei Zeilen auswählen, wird kein LF-Zeichen eingefügt, wenn die beiden Zeilen durch Umbrechen am rechten Rand entstehen.Wenn Sie nun die Ausgabe von
printf
in der CLIPBOARD-X11
Auswahl speichern möchten, tun Sie dies am besten direkt wie folgt mit:Beachten Sie, dass , wenn Sie fügen , dass in den
xterm
meisten anderen Terminals oderxterm
ersetzt eigentlich , dass\n
mit ,\r
denn das ist das Zeichenxterm
sendet , wenn Sie drücken Enter(und der Terminal - Treiber kann es übersetzen zurück zu\n
).quelle
X11
übernimmt die Auswahl zum Kopieren und Einfügen in Terminalemulatoren wiexterm
oderputty
unter Unix. Andere Terminalemulatoren verfügen möglicherweise über einen eigenen Mechanismus zum Kopieren und Einfügen sowie über Möglichkeiten zum Speichern beliebiger Inhalte, z. B. die Befehlereadbuf
undregister
im GNU-Bildschirm.