Hallo,
ich habe reichlich Projekte mit jeweils reichlich vielen (vhdl-)Dateien,
in denen Tabulatoren zur Formatierung verwendet werden. Da diese in
anderen Editoren durch die unterschiedliche Anzahl der Leerzeichen pro
Tabulator immer total zerissen aussehen, suche ich nach einer
Möglichkeit, in allen Dateien batch-artig alle Tabulatoren durch x
Leerzeichen zu ersetzen.
Die Mühe, jede einzelne Datei zu öffnen und da dann alle zu ersetzen,
möchte ich mir wirklich ungern machen, dafür sind es einfach zu viele
Dateien.
Hat da jemand 'ne Idee oder weiß ein Programm, mit dem das gut geht?
Danke schonmal für alle Hinweise!
z.B. http://de.wikipedia.org/wiki/Vi
Wie war doch der Spruch: Mit einer Frau kann man eine Firma am schönsten
ruinieren - mit einem Computer am SCHNELLSTEN?
Für sowas nimmt man klassischerweise sed ("stream editor") aus dem
Unix-Baukasten. Für Win guckst Du hier:
http://sourceforge.net/projects/unxutils/
Die Aufrufsyntax ist gewöhnungsbedürftig, aber dann gehts von selber ...
Liebe Editorvorschlager, ihr habt aber schon gelesen, dass ich eben
NICHT jede Datei einzeln öffnen will, um dann den mir selbstverständlich
seit geraumer Zeit bekannten Ersetzen-Dialog zu bemühen?
@yalu (oder andere sed-Experten):
Danke für die Syntax, das hat mir sehr geholfen. Wenn du mir jetzt noch
sagst, dass und wie das auch in Unterordnern suchen kann, damit ich die
Chose nicht auf jeden Ordner einzeln anwenden muss, bist du mein
absoluter Held. Für mitlesende Windowser, der funktionierende Befehl
unter Win32 lautet bisher: sed -i -e "s/\t/ /g" *.vhd
> Liebe Editorvorschlager, ihr habt aber schon gelesen, dass ich eben> NICHT jede Datei einzeln öffnen will, um dann den mir selbstverständlich> seit geraumer Zeit bekannten Ersetzen-Dialog zu bemühen?
richtige Editoren haben die möglichkeit "suchen und ersetzen in
Dateien". Ultraedit z.b. es gibt davon auch eine Trail version.
Dicke Finger schrieb:
> Wenn du mir jetzt noch sagst, dass und wie das auch in Unterordnern> suchen kann, damit ich die Chose nicht auf jeden Ordner einzeln> anwenden muss, bist du mein absoluter Held.
Wer wollte nicht schon immer der absolute Held der Dicken Finger sein
;-)
Sicher ist in dem Paket, das den sed enthält, auch ein find mit
drin. Damit kannst du rekursiv nach allen Dateien mit bestimmten
Eigenschaften (in diesem Fall mit dem Namen *.vhd) suchen und auf jede
einen Befehl anwenden (in diesem Fall sed).
Die erste Variante sucht im aktuellen Verzeichnis und allen
Unterverzeichnissen:
find basisverzeichnis -name "*.vhd" -exec sed -i -e "s//\t/ /g" {} ;
Ohne das zusätzliche / beim Parameter s geht gar nichts, dafür ist das \
am Ende nicht notwendig. So läuft es auch erstmal an, Problem ist nur,
dass da einige Verzeichnisse mit Leerzeichen drin sind, und die werden
von sed anscheinend als Trennungszeichen interpretiert, das sucht dann
also jeweils in den Teilen, die durch das Leerzeichen getrennt sind, und
diese Verzeichnisse existieren natürlich nicht.
Dafür fällt es mir schwer, eine Lösung zu finden, da der Suchbegriff
"find" anders als sed durchaus zahlreiche Ergebnisse liefert, die so gar
nichts mit dem Linux-Befehl zu tun haben.
Hast du noch einen Tipp in der Hinterhand? ;)
> Problem ist nur,> dass da einige Verzeichnisse mit Leerzeichen drin sind
einfach ein paar " verteilen.
find basisverzeichnis -name "*.vhd" -exec sed -i -e "s//\t/ /g" "{}" ;
oder
find basisverzeichnis -name "*.vhd" -exec sed -i -e "s//\t/ /g" \"{}\"
;
Das ganze Anführungszeichen- und Backslash-Gedöns ist Shell-abhängig und
wird von der Windows-Eingabeaufforderung anders gehandhabt als von einer
Unix-Shell. Falls die Vorschläge von Peter nicht helfen sollten, kannst
du versuchen, find und sed aus der in den UnxUntils enthaltenen Shell
(sh.exe) heraus zu starten.
Ich habe hier kein lauffähiges Windows, deswegen kann ich das nicht
testen. Das, was ich weiter oben geschrieben habe, funktioniert unter
Linux problemlos, auch bei Leerzeichen in Datei- und Verzeichnisnamen.
> find basisverzeichnis -name "*.vhd" -exec sed -i -e "s//\t/ /g" {} ;>> Ohne das zusätzliche / beim Parameter s geht gar nichts, dafür ist das> \ am Ende nicht notwendig.
Das riecht irgendwie danach, dass das sed-Skript "s//\t/ /g" trotz der
Anführungszeichen in zwei Teile aufgespalten wird. Wenn das so ist, tut
der sed-befehl hinterher etwas ganz anderes. Aber auch hier sollte der
Aufruf aus der Shell helfen.
> Liebe Editorvorschlager, ihr habt aber schon gelesen, dass ich eben> NICHT jede Datei einzeln öffnen will,
Wie schon gesagt wurde: Nimm Notepad++ (verwende ich auch, Top Teil), da
geht das ohne Stress mit wenigen Mausklicks und ohne kryptische
Kommandos
Hmm, die ganzen sed-Varianten ueberzeugen mich nicht so recht, da ein
tab nicht immer mit 3, 4 oder 8 Leerzeichen ersetzt werden muss, sondern
abhaengig von der Spalte in der das Tab vorkommt.
Vim eignet sich gut, um solchen Tabs zu ersetzen. Notepad++ vielleicht
auch, aber diesen Editor kenne ich nicht.
Unter Vim wuerde ich das so machen:
1) Anlegen einer Konfigurationsdatei fuer Vim (~/.vimrc unter Unix oder
$HOME\_vimrc unter Windows) mit dem Inhalt
1
"tabs
2
set tabstop=4
3
set softtabstop=4
4
set shiftwidth=4
5
set expandtab
2) in jedem File ein ":%expandtab" ohne Gaensefuesschen eingeben.
Punkt 2) kann man auch automatisieren, z.B. mit einem Macro
1
:map <F2> :%expandTAB<ENTER>:wn<ENTER>
Jedesmal wenn man F2 drueckt, werden alle Tabs in der Datei expandiert,
die Datei wird gespeichert und die naechste Datei geladen.
Nun muss nur noch Vim mit der Liste aller Dateien aufgerufen werden.
Unter Linux wuerde ich folgendes machen:
Ich wollte ja schon gestern etwas sagen, habs aber dann mal lieber
gelassen.
Die ganze Geschichte hängt doch wohl davon ab, welcher Tab-Abstand zum
Zeitpunkt der Erstellung der Datei da war. Wenn sich einer sicher ist,
immer denselben Abstand eingestellt zu haben, für den ist die
Ruckzuckmethode mit find und sed optimal (UTF-8 sei mal nicht erwähnt).
Andernfalls muss man vor der Konvertierung wissen wie der Tab-Abstand in
jeder einzelnen Datei war. Was sollte man denn da noch automatisieren?
So, vielen Dank nochmal an alle Tippgeber, schlussendlich habe ich eine
andere und recht einfache Möglichkeit gefunden, nämlich den TextCrawler.
Die Texteditormethode schlug bei mir zumindest mit Notepad++ fehl, da
sich dies mit höherer Dateianzahl immer weiter aufblies und sich
irgendwann selbst blockierte.
Der Tipp mit der Shell kam ein bisschen zu spät, aber ich werde dran
denken, wenn ich mal andere solche Sachen machen muss, bei denen der
TextCrawler vielleicht scheitert.
In den GNU-Coreutils gibt es ein Programm, um Tabulatoren in Leerzeichen
umzuwandeln (expand) und eines, um Leerzeichen in Tabulatoren
umzuwandeln (unexpand). Meine Antwort kommt spät, aber ich habe diesen
Thread kürzlich per Google gefunden und jetzt eine bessere Möglichkeit
als sed. Vielleicht nützt mein Post einigen Suchern.
> kommt spät
Auch spaet:
Es lebe der TAB!
uncrustify kann die vielen sinnlosen SPCse durch TABse ersetzen.
"There are currently 412 options and minimal documentation.
Try UniversalIndentGUI and good luck."
Wenn ich keine Software für Deine spezielle Ersetzungslogik fände, würde
ich einfach in VBA für Excel ein Verzeichnis rekursiv durchlaufen und
dann auf jede einzelne Datei den Algorithmus für die gewünschte
Ersetzung loslassen.
Unter Windows geht das wohl auch mit Windows Scripting Host, aber das
ist nicht so schön zu debuggen wie bei VBA, meine ich.
Unter VBA bei Excel kann man auch immer bequemen die Tabellen mit
irgendwelchen wichtigen Logging-Inhalten aus VBA vollschreiben.
Für das rekursive Durchlaufen einer Ordnerstruktur findest Du genügend
einsatzfähige Codel-Schnippsel im Netz.
Die Arbeit reduziert sich damit auf die Ersetzungslogik.
Man kann die Ersetzung auch von VBA aus machen. Ist auch kein Problem,
solange das file Klartext und keine Sonderzeichen hat. In Notepad kann
man übrigens mehrere files per mousecklick gleichzeitig laden und dann
in allen Dateien suchen und ersetzen.
wie trage ich in einer graphischen Maske
z.B. in Notepad "suchen und ersetzen"
Ein "tab" zum Suchen ein?
welchen "Schtring" bräuchte man da?
wenn man "tab" drückt, springt der Cursor in das nächste Eingabefeld.
● J-A V. schrieb:> wie trage ich in einer graphischen Maske> z.B. in Notepad "suchen und ersetzen">> Ein "tab" zum Suchen ein?> welchen "Schtring" bräuchte man da?>> wenn man "tab" drückt, springt der Cursor in das nächste Eingabefeld.
Doku zum $EDITOR lesen und lernen.
Es geht eben doch nicht ohne die /verhasste schrecklich kryptische
Syntax/
Kann man einen Tab nicht direkt einfügen, so geht fast immer:
Einen Tab im Text eingeben; diesen Markieren und in die Zwischenablage
übernehmen; anschließend (Trommelwirbel) Einfügen. Löschen nicht
vergessen.
Beim automatischen Ersetzen von Tabulatoren gibt es noch einen mächtigen
Pferdefuß: Das geht nur bei der Verwendung von Fonts mit fester Breite.
Nur dann stimmt die Berechnung der angenommenen Tabulatorpositionen.