Forum: PC Hard- und Software Tabs durch Leerzeichen ersetzen


von Max W. (Gast)


Lesenswert?

Ich suche ein Commandline-Tool um die nicht ungewöhnliche Aufgabe zu 
lösen, Tabs durch Leerzeichen zu ersetzen.

Ich hatte da mal irgendwo einen Fetzen im Internet gefunden, das war 
eigentlich nur ein sed-Aufruf. Und es wurden leider nur Stur die Tabs 
durch 4 Leerzeichen ersetzt. Allerdings müsste ja die Position des 
ersten Tabs überprüft und gegebenfalls durch weniger Leerzeichen ersetzt 
werden, um Verschiebungen zu vermeiden.

Hat da jemand zufällig was in der Richtung? (bash, perl, python)

Gruß

von Der E. (rogie)


Lesenswert?

Wie viele Leerzeichen durch ein TAB dargestellt werden, ist alleine 
Sache des Editors/Betrachters und nicht in der Datei abgespeichert.

Tabs kann man z.B. auch mit Notepad++ ersetzen.

von Max W. (Gast)


Lesenswert?

Der Entwickler schrieb:
> Wie viele Leerzeichen durch ein TAB dargestellt werden, ist alleine
> Sache des Editors/Betrachters und nicht in der Datei abgespeichert.
Genau. Oder eben im Skript/Tool hinterlegt, der diese Wandlung 
automatisiert vornimmt. Luxus wäre natürlich, diese Zahl dem Skript/Tool 
als Parameter übergeben zu können.

> Tabs kann man z.B. auch mit Notepad++ ersetzen.
Kann man dieses Feature von der Kommandozeile ansprechen?

von Stefan P. (form)


Lesenswert?

Hast Du ein paar Zeilen Beispieltext wie es aussehen soll? 
(Vorher/Nachher)

Das mit der "Position des ersten TABs" verstehe ich nicht so recht - 
Geht es um C-Code o.ä.? TABs haben dort doch keine Position, sondern es 
sind halt mehrere TABs nacheinander.

von Michael W. (Gast)


Lesenswert?

Man kann bei Notepad Makros aufzeichnen, meine ich, gfs geht es damit.

von Peter II (Gast)


Lesenswert?

Stefan P. schrieb:
> Das mit der "Position des ersten TABs" verstehe ich nicht so recht -
> Geht es um C-Code o.ä.? TABs haben dort doch keine Position, sondern es
> sind halt mehrere TABs nacheinander.

er meint damit, das bei (einigen) Editoren die Tabs immer zu einer 
Position die durch 4 Teilbar ist springen.

ein
[space][Tab]text]
[space][space][Tab]text]
[space][space][space][Tab]text]

sieht gleich aus, der text beginn jeweils an Pos 4.

von Max W. (Gast)


Lesenswert?

Peter II schrieb:
> er meint damit, das bei (einigen) Editoren die Tabs immer zu einer
> Position die durch 4 Teilbar ist springen.
>
> ein
> [space][Tab]text]
> [space][space][Tab]text]
> [space][space][space][Tab]text]
>
> sieht gleich aus, der text beginn jeweils an Pos 4.

Genau das.
Anstatt also blind einen Tab durch exakt n Leerzeichen zu ersetzen muss 
n abhängig von der Position berechnet werden (n = SPACE_FOR_TAB - (pos % 
SPACE_FOR_TAB), oder so ähnlich).

Wundert mich dass es sowas noch nicht gibt, muss mich wohl doch in perl 
einarbeiten.

von ...-. (Gast)


Lesenswert?

Der Notepad++ kann genaus das verlangte.

von Max W. (Gast)


Lesenswert?

...-. schrieb:
> Der Notepad++ kann genaus das verlangte.

Kann man dieses Feature von der Kommandozeile ansprechen?

von Yalu X. (yalu) (Moderator)


Lesenswert?


von Dirk B. (dirkb2)


Lesenswert?

Das Programm expand macht das.

Gibt es auch für Windows (bei den GnuTools ist es dabei)

von Dirk B. (dirkb2)


Lesenswert?

Dirk B. schrieb:
> Das Programm expand macht das.
>
> Gibt es auch für Windows (bei den GnuTools ist es dabei)

http://gnuwin32.sourceforge.net/packages/coreutils.htm

von Oliver S. (oliverso)


Lesenswert?

Max W. schrieb:
> war
> eigentlich nur ein sed-Aufruf.

Eigentlich kann sed alles. Du musst nur jemanden finden, der dir den 
regulären Ausdruck dazu bastelt ;)

Oliver

von Norbert (Gast)


Lesenswert?

Oliver S. schrieb:
> Max W. schrieb:
>> war
>> eigentlich nur ein sed-Aufruf.
>
> Eigentlich kann sed alles. Du musst nur jemanden finden, der dir den
> regulären Ausdruck dazu bastelt ;)
>
> Oliver

In diesem speziellen Fall würde ich lieber awk nehmen, das Werkzeug ist 
ein wenig universeller.

Im Anfangsbereich
1
BEGIN{...}
 die Größe eines Tabstops definieren.
Zeilenweise einlesen,
In Schleife die Position(en) der/des Tabs bestimmen,
passende Menge ' ' einfügen,
wegschreiben, fertich!

von Peter II (Gast)


Lesenswert?

Norbert schrieb:
> Im AnfangsbereichBEGIN{...} die Größe eines Tabstops definieren.
> Zeilenweise einlesen,
> In Schleife die Position(en) der/des Tabs bestimmen,
> passende Menge ' ' einfügen,
> wegschreiben, fertich!

und wo ist das der Vorteil von AWK? Das kann man genauso in Perl machen.

von Dirk B. (dirkb2)


Lesenswert?

Peter II schrieb:
> und wo ist das der Vorteil von AWK? Das kann man genauso in Perl machen.

Was ist der Vorteil von Perl, wenn man es genauso machen kann?

Auf *ix ist AWK dabei. Perl meist auch. expand aber auch (das macht das 
gewünschte).

Auf Windows muss man jedes der Programm extra installieren.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Hier gibt es jede Menge Sed-Skripte, u.a. auch für Tab-Expansion:

  http://sed.sourceforge.net/grabbag/scripts/

(nach "Expand tabs to spaces" suchen)

Ansonsten würde ich mich aber Dirk B. anschließen und das expand-Tool
empfehlen, das man meist (evtl. ohne es zu wissen) sowieso schon
installiert hat.

von Max W. (Gast)


Lesenswert?

Danke Yalu, das werd ich mir mal alles zu Gemüte führen.

Nichtsdestotrotz hab ich in der Zwischenzeit mal folgendes 
zusammengeschustert, das macht (bis jetzt) genau was es soll:
1
inFile = open("./test.txt", "r")
2
outFile = open("./test2.txt", "w")
3
4
for line in inFile:
5
    idx = line.find('\t')
6
    while(idx != -1):
7
        spaceCnt = 4 - (idx % 4)
8
        if (spaceCnt == 1):
9
            line = line.replace("\t", " ", 1)
10
        elif (spaceCnt == 2):
11
            line = line.replace("\t", "  ", 1)
12
        elif (spaceCnt == 3):
13
            line = line.replace("\t", "   ", 1)
14
        elif (spaceCnt == 4):
15
            line = line.replace("\t", "    ", 1)
16
        idx = line.find('\t')
17
        
18
    outFile.write(line)
19
20
inFile.close()
21
outFile.close()

Ist mein erster Kontakt mit Python und ich hab das nur so 
zusammengepfriemelt. Execptions werden noch nicht aufgefangen. Und die 
hartcodierte "4" würd ich gern durch Generik ersetzen, aber für 15min 
basteln bin ich schon recht zufrieden :-)

Und ja, ich weiß dass Perl für sowas wahrscheinlich performanter ist und 
mein Python-Stil vermutlich murks ist :p

von Yalu X. (yalu) (Moderator)


Lesenswert?

Das sieht doch schon gut aus.

Für beliebige Tab-Breiten ersetzt du einfach dieses
1
        spaceCnt = 4 - (idx % 4)
2
        if (spaceCnt == 1):
3
            line = line.replace("\t", " ", 1)
4
        elif (spaceCnt == 2):
5
            line = line.replace("\t", "  ", 1)
6
        elif (spaceCnt == 3):
7
            line = line.replace("\t", "   ", 1)
8
        elif (spaceCnt == 4):
9
            line = line.replace("\t", "    ", 1)
10
        idx = line.find('\t')

durch dieses:
1
        spaceCnt = tabWidth - (idx % tabWidth)
2
        line = line.replace("\t", spaceCnt * " ", 1)
3
        idx = line.find('\t')

In tabWidth muss dabei der entsprechende Wert (4, 8 oder was auch immer)
stehen.

: Bearbeitet durch Moderator
von Uhu U. (uhu)


Lesenswert?

Der Entwickler schrieb:
> Wie viele Leerzeichen durch ein TAB dargestellt werden, ist alleine
> Sache des Editors/Betrachters und nicht in der Datei abgespeichert.

Nicht ganz, es gibt Ausnahmen: Vim z.B. versteht folgende Zeile irgendwo 
im Text:
1
# vim:ts=3:sw=3:

Das bedeutet tabsize=3 und shiftwidth=3. Der Editor weiß dann, wie er 
die Datei darstellen muss.

Das # am Zeilenanfang ist das Kommentarzeichen der jeweiligen 
Programmiersprache - kann also auch // o.Ä. sein.

von Uhu U. (uhu)


Lesenswert?

Peter II schrieb:
> und wo ist das der Vorteil von AWK? Das kann man genauso in Perl machen.

Ja, das kann man. Allerdings hat AWK nicht so eine kranke Syntax wie 
Perl - das macht die Sache für Nicht-Perlprogrammierer deutlich 
einfacher...

von Εrnst B. (ernst)


Lesenswert?

Uhu Uhuhu schrieb:
> Ja, das kann man. Allerdings hat AWK nicht so eine kranke Syntax wie
> Perl - das macht die Sache für Nicht-Perlprogrammierer deutlich
> einfacher...

ist ja kein Problem.
Perl liefert "a2p" mit, damit kann man das AWK-Script gleich wieder 
ver-perl-en.

von Norbert (Gast)


Lesenswert?

Yalu X. schrieb:
> Das sieht doch schon gut aus.
>
> Für beliebige Tab-Breiten ersetzt du einfach dieses
>
>
1
>         spaceCnt = 4 - (idx % 4)
2
>         if (spaceCnt == 1):
3
>             line = line.replace("\t", " ", 1)
4
>         elif (spaceCnt == 2):
5
>             line = line.replace("\t", "  ", 1)
6
>         elif (spaceCnt == 3):
7
>             line = line.replace("\t", "   ", 1)
8
>         elif (spaceCnt == 4):
9
>             line = line.replace("\t", "    ", 1)
10
>         idx = line.find('\t')
11
>

und dann ersetzt du das durch:
1
line = line.replace("\t", " "*spaceCnt, 1)
;-)

von Norbert (Gast)


Lesenswert?

Εrnst B✶ schrieb:
> Uhu Uhuhu schrieb:
>> Ja, das kann man. Allerdings hat AWK nicht so eine kranke Syntax wie
>> Perl - das macht die Sache für Nicht-Perlprogrammierer deutlich
>> einfacher...
>
> ist ja kein Problem.
> Perl liefert "a2p" mit, damit kann man das AWK-Script gleich wieder
> ver-perl-en.

Ab hier wird's jetzt aber widerlich ;)

von petar (Gast)


Lesenswert?

Max W. schrieb:
> Allerdings müsste ja die Position des
> ersten Tabs überprüft und gegebenfalls durch weniger Leerzeichen ersetzt
> werden, um Verschiebungen zu vermeiden.
Liest sich für mich eher nach einer Aufgabe für ein Einrückungstools, 
evtl astyle? Oder sed und dann astyle?
1
sed 's/\t/        /g' in.dat > out.dat
1
astyle --style=linux file.dat

von Uhu U. (uhu)


Lesenswert?

Εrnst B✶ schrieb:
> Perl liefert "a2p" mit, damit kann man das AWK-Script gleich wieder
> ver-perl-en.

Das ist dann für durch Perl versaute Programmierer, die mit AWK nicht 
klar kommen...

von Norbert (Gast)


Lesenswert?

Uhu Uhuhu schrieb:
> Εrnst B✶ schrieb:
>> Perl liefert "a2p" mit, damit kann man das AWK-Script gleich wieder
>> ver-perl-en.
>
> Das ist dann für durch Perl versaute Programmierer, die mit AWK nicht
> klar kommen...

Mir fallen da auf Anhieb zwei Kollegen ein, die am liebsten alles 
Mögliche in Perl programmieren würden.

Da kommt einem sofort der Satz in den Sinn:
1
Wenn man einen Hammer in der Hand hat,
2
dann sieht plötzlich alles wie ein Nagel aus!

Nachsatz:

Nur gut das das keine Java oder .NET Fans sind;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.