Ich habe einige Fragen zum Stapelüberlauf durchgesehen, um zu erfahren, wie Leerzeichen in Tabulatoren konvertiert werden können, ohne zu finden, was ich benötige. Es scheint mehr Fragen zu geben, wie Tabulatoren in Leerzeichen konvertiert werden, aber ich versuche das Gegenteil zu tun.
In Vim
ich versucht habe :retab
und :retab!
ohne Glück, aber ich glaube , die sind eigentlich für sowieso von Tabs zu Leerzeichen gehen.
Ich habe beide expand
und unexpand
an der Eingabeaufforderung ohne Glück versucht .
Hier ist die betreffende Datei:
Wie kann ich führende Leerzeichen mithilfe von entweder Vim
oder der Shell in Tabulatoren konvertieren ?
sed "s/ +/`echo -e '\t'`/g" < input.py > output.py
scheint das erste Beispiel ( ) alle Leerzeichen zu konvertieren, nicht nur führende Leerzeichen. Im zweiten Beispiel (sed "s/^ +/`echo -e '\t'`/g" < input.py > output.py
) wird nur das erste Leerzeichen in jeder Zeile durch eine Registerkarte ersetzt und der Rest verbleibt.find
,awk
und Blackjack (zu lange es in den Kommentaren zu verlassen, obwohl)Antworten:
Wenn Sie Vim verwenden, um alle führenden Bereiche zu erweitern (breiter als
'tabstop'
), haben Sie zu Recht verwendet,retab
aber zuerst sichergestellt, dass sie'expandtab'
zurückgesetzt werden (:verbose set ts? et?
ist Ihr Freund).retab
nimmt einen Bereich , so spezifiziere ich normalerweise%
"die gesamte Datei" an.Bevor ich so etwas mache (besonders mit Python-Dateien!), Setze ich normalerweise
'list'
, so dass ich sehe das Leerzeichen und ändern.Ich habe die folgende Zuordnung in meinem
.vimrc
dafür:quelle
:set noet
,:set tabstop=2
,:retab!
,:%retab!
,:set tabstop=1
,:retab!
,:%retab!
%
. Das F2-Mapping entspricht genau der Eingabe .:set noet ts=2 |%retab!
:%retab!
funktioniert immer noch. Ich war verwirrt mit==
, etc , die tut die preserveindent Einstellung respektieren.:set tabstop=4
1 - Wenn Sie Leerzeichen haben und Tabulatoren möchten.
Zunächst müssen Sie entscheiden, wie viele Leerzeichen eine einzelne Registerkarte haben soll. Angenommen, Sie haben Zeilen mit führenden 4 Leerzeichen oder 8 ... Dann stellen Sie fest, dass ein Tab wahrscheinlich 4 Leerzeichen enthalten soll. Mit diesen Informationen tun Sie Folgendes:
Hier gibt es ein Problem! Diese Befehlsfolge sucht nach Ihrem gesamten Text, nicht nur nach Leerzeichen am Zeilenanfang. Das bedeutet, dass eine Zeichenfolge wie:
"Hey,␣this␣␣␣␣is␣4␣spaces"
wird"Hey,␣this⇥is␣4␣spaces"
, aber es ist nicht! Es ist ein Tab!.Um dieses kleine Problem zu lösen, empfehle ich
search
stattdessen aretab
.Bei dieser Suche wird in der gesamten Datei nach Zeilen gesucht, die mit einer beliebigen Anzahl von Tabulatoren beginnen, gefolgt von 4 Leerzeichen, und durch die Anzahl der gefundenen Tabulatoren plus einer ersetzt.
Dies wird leider nicht sofort ausgeführt!
Die Datei enthält zunächst Zeilen, die mit Leerzeichen beginnen. Die Suche konvertiert dann nur die ersten 4 Leerzeichen in eine Registerkarte und lässt die folgenden ...
Sie müssen den Befehl wiederholen. Wie oft? Bis du eine bekommst
pattern not found
. Ich kann mir noch keine Möglichkeit vorstellen, den Prozess zu automatisieren. Aber wenn Sie dies tun:Sie sind wahrscheinlich fertig. Dieser Befehl wiederholt das letzte Suchen / Ersetzen zehnmal. Es ist unwahrscheinlich, dass Ihr Programm so viele Einrückungen hat. Wenn ja, wiederholen Sie einfach noch einmal
@@
.Nun, nur um die Antwort zu vervollständigen. Ich weiß, dass Sie nach dem Gegenteil gefragt haben, aber Sie wissen nie, wann Sie Dinge rückgängig machen müssen.
2 - Sie haben Tabulatoren und möchten Leerzeichen.
Entscheiden Sie zunächst, in wie viele Leerzeichen Ihre Registerkarten konvertiert werden sollen. Nehmen wir an, Sie möchten, dass jede Registerkarte 2 Leerzeichen enthält. Sie tun dann:
Dies hätte das gleiche Problem mit Zeichenfolgen. Aber da es ein besserer Programmierstil ist, keine harten Tabulatoren in Strings zu verwenden, tun Sie hier tatsächlich etwas Gutes. Wenn Sie wirklich eine Registerkarte in einer Zeichenfolge benötigen, verwenden Sie
\t
.quelle
ex command
, denn das wäre das, was sich in der Funktion befindet. Und nein, es ist nicht selten. Sie müssen nur Zeichenfolgen mit Leerzeichen haben, um ein Durcheinander zu haben. Gar nicht selten. Ich bin da. Danke für den Kommentar.^
Symbols, um die Suche am Zeilenanfang zu starten, das Risiko eingehen, Leerzeichen innerhalb von Zeichenfolgen zu ändern. Mit der^
Sie garantieren, dass Sie seit Beginn der Zeile nur Leerzeichen und Tabulatoren ändern, also Einrückung. Wenn Sie sicher sind, dass es in Ordnung ist, alles auf einmal zu tun, entfernen Sie das^
und führen Sie es nur einmal aus mit::%s/\(^I*\)␣␣␣␣/\1^I/g
Übersetzung: Suchen Sie nach jeder Instanz von 4 aufeinanderfolgenden Leerzeichen (nach dem Zeichen =), jedoch nur, wenn die gesamte Zeile bis zu diesem Punkt ein Leerzeichen ist (dies verwendet die Behind-Behauptung mit der Breite Null
\@<=
). Ersetzen Sie jede gefundene Instanz durch ein Tabulatorzeichen.quelle
:%s/\(^\s*\)\@<= /\t/g
- setzen Sie die entsprechende Anzahl von Leerzeichen (um 4 Leerzeichen in 1 Tabulator umzuwandeln, setzen Sie 4 Leerzeichen ein) direkt nach dem<=
Ändert alle Leerzeichen in Tabulator:% s / \ s / \ t / g
quelle
Linux: mit
unexpand
(undexpand
)Hier ist eine sehr gute Lösung: https://stackoverflow.com/a/11094620/1115187 , hauptsächlich, weil * nix-Dienstprogramme verwendet werden:
Linux: Benutzerdefiniertes Skript
Meine ursprüngliche Antwort
Bash-Snippet zum Ersetzen von Einrückungen mit 4 Leerzeichen (es gibt zwei
{4}
im Skript) durch Tabulatoren in allen.py
Dateien im./app
Ordner (rekursiv):Es werden keine 4 Leerzeichen in der Mitte oder am Ende geändert.
Wurde unter Ubuntu 16.0x und Linux Mint 18 getestet
quelle
In meinem Fall hatte ich mehrere Leerzeichen (Felder wurden durch ein oder mehrere Leerzeichen getrennt), die ich durch eine Registerkarte ersetzen wollte. Folgendes hat es getan:
quelle
Wenn Sie GNU coreutils installiert ist , prüfen
%!unexpand --first-only
oder für 4-Raum - Tabs, betrachten%!unexpand -t 4 --first-only
(--first-only
vorhanden ist nur, wenn Sie aus Versehen wurden Aufrufunexpand
mit--all
).Beachten Sie, dass dadurch nur die Leerzeichen vor den vorgeschriebenen Tabulatoren ersetzt werden, nicht die darauf folgenden Leerzeichen. Sie werden keinen visuellen Unterschied in vim sehen, es sei denn, Sie zeigen Registerkarten wörtlicher an. Zum Beispiel
~/.vimrc
enthält meineset list listchars=tab:▸┈
(ich vermute, das ist der Grund, warum Sie dachten, dassunexpand
es nicht funktioniert hat).quelle
Um mit Vim eine Reihe von Dateien (z. B. alle * .ts-Dateien in einer Verzeichnishierarchie) von beispielsweise 2 bis 4 Leerzeichen neu zu erstellen, können Sie dies über die Befehlszeile versuchen:
Damit werden
find
alle übereinstimmenden Dateien an übergebenxargs
(die Option -print0 bei find funktioniert mit der Option -0 an xargs, um Dateien mit Leerzeichen im Namen zu verarbeiten).xargs führt vim im Ex-Modus aus (
-e
) für jede Datei aus, wobei der angegebene ex-Befehl ausgeführt wird, bei dem es sich tatsächlich um mehrere Befehle handelt, um die vorhandenen führenden Leerzeichen in Tabulatoren zu ändern, den Tabulator zurückzusetzen und die Tabulatoren wieder in Leerzeichen zu ändern und schließlich zu speichern und zu beenden.Das Ausführen im Ex-Modus verhindert dies:
Vim: Warning: Input is not from a terminal
für jede Datei.quelle
Einfaches Python-Skript:
quelle