DOS <--> Unix Converter [Bitte Testen!]

Code-Stücke können hier veröffentlicht werden.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Auch wenn ich nur die hälfte verstanden habe :)
Ich würde nur Dateinamen verarbeiten und Windowsbenutzern sagen, sie sollen gefälligst eine ordentliche Shell benutzen.
Dagegen hab ich nichts... :) Mal abgesehen von der PowerShell in Vista..

Öhmm ich habe mir gerade eine Lösung erarbeitet. Bin noch am schreiben.

Werde dann ggf. hier editieren...


MfG EnTeQuAk


EDIT:

So. Fast Fertig. Allerdings konnte ich zu einer Frage immo fast nichts finden.
Und zwar hat Gerold in seinen Scripten unix2dos.py und dos2unix.py vor dem Umwaldeln erst noch folgendes gemacht:

Code: Alles auswählen

# Bsp. bei unix2dos.py
for line in infile:
        line = line.replace("\r\n", "\n")
        line = line.replace("\n", "\r\n")
        outfile.write(line)
Warum genau hat er erst "überprüft", ob auch alle Zeilenumbrüche gleich sind?

Macht das Sinn. Gibt es die Möglichkeit eines "MischMasches". Wenn ja. Dann hätte ich für die Automatische Konvertierung zum jeweils anderen Zeilenumbruch ein arges Problem.

MfG EnTeQuAk
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

EnTeQuAk hat geschrieben:

Code: Alles auswählen

# Bsp. bei unix2dos.py
for line in infile:
        line = line.replace("\r\n", "\n")
        line = line.replace("\n", "\r\n")
        outfile.write(line)
Warum genau hat er erst "überprüft", ob auch alle Zeilenumbrüche gleich sind?
Hi EnTeQuAk!

Das hat mehrere Gründe:
- Wenn eine Datei mit verschiedenen Editoren unter verschiedenen Betriebssystemen bearbeitet wird, dann ist eine Mischung der Zeilenendungen nicht auszuschließen.
- Ich weiß nicht wie ``f = file("dateiname", "rU") auf gemischte Zeilenumbrüche reagiert. Ausprobieren wollte ich es nicht, deshalb habe ich die Umwandlung selbst in die Hand genommen.
- Was passiert, wenn die Datei bereits nach DOS umgewandelt wurde? --> Aus "\r\n" würde beim Replace "\r\r\n" werden.

Durch das vorherige Replace schlage ich also mehrere Fliegen mit einer Klappe.

Um diese Frage auch noch aus dem Weg zu räumen: Ich arbeite deshalb mit einer temporären Datei und nicht direkt im Speicher (was einfacher wäre), da ich nicht weiß, wie groß die Dateien werden können, die umgewandelt werden sollen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Sehr gute Erklärung :)

So weit so gut ganz gut verstanden.

Ich überlege dann mal, was es sonst so für Möglichkeiten gibt.

Ich werd schon was finden. :D

Danke!

MfG EnTeQuAk


EDIT:

bei genaueren Nachdenken. Es gibt direkt keine Möglichkeit, 100%ig automatisch zwischen DOS und Unix Dateien zu unterscheiden.
hmm... ma schaun. vllt. finde ich noch was...

hat jmd ne Idee?
BlackJack

Naja warum Unterscheiden und nicht erstmal alle "gleichmachen" und dann mit den gewünschten Zeilenenden rausschreiben. Wobei der "Universal" Dateimodus hier hilfreich sein kann, wie schon erwähnt wurde.

Ich glaube ich würde das mit der temporären Datei so lösen, dass ich erst das Original nach `name.ext.bak` umbenenne und dann die konvertierte Datei unter dem Originalnamen erstelle. So ist sichergestellt, dass man immer noch das Original hat, auch wenn man mittendrin das Programm abbricht. Ob die Backupdatei nach erfolgreicher Konvertierung gelöscht wird, könnte man als Option einbauen. Voreinstellung wäre `Nein`. Bin halt ein wenig paranoid. :-)

Zu der "Hälfte" die Du von meinem letzten Post verstanden hast: Welche war es denn? :-)
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Was ich nicht verstanden habe :)

Das untere mit der Shell. ab dem Expandiert usw... das ist für mich net ganz nachvollziehbar allerdings auch etwas OT oder?
(Wenn ich es richtig verstanden habe).


So ich bin nun mitlerweile doch wieder soweit, das ich die Umwandlung DOS-Unix doch vom Benutzer vorgegeben wird.

Eventuell baue ich eine Unterscheidung ein, die erkennt, das es bereits eine DOS bzw. Unix Datei ist und darauf hinweißt.

Die Idee mit den Baks ist ne gute IDee :D Vorallem zum testen. So brauch ich net immer zum Rechner meines Vaters rüberrennen und ne Datei erstellen :) :) :) :) :)

Ich muss mich nur noch an die halbwegs logische belegung der Argumente machen. Mal schauen, was ich da so hinbekomme :)

Wird schon.

Nur mal so zwischendurch:
Ihr seit Klasse! So viel Antworten bekomme ich selten in anderen Foren!
Danke!


MfG EnTeQuAk
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Berücksichtigt ihr eigentlich, dass die zu ersetzenden Zeilenumbrüche nur am Ende der Zeile ersetzt werden dürfen? Sobald da nämlich z.B. ein Newline zum enthaltenen Code gehört, geht da einiges den Bach runter.

Auch sollte man vielleicht Mac OS-Zeilenumbrüche (\r) berücksichtigen.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Auch sollte man vielleicht Mac OS-Zeilenumbrüche (\r) berücksichtigen.
Ahh endlich sagts mal jmd :)

Werde ich gerne machen.


Aber das mit den Newline Zeichen im Code ist wohl war.

das macht das ganze schwerer.

Mal schauen. Erstmal eins. Das andere kommt später :D


fG EnteQuAk
BlackJack

EnTeQuAk hat geschrieben:Was ich nicht verstanden habe :)

Das untere mit der Shell. ab dem Expandiert usw... das ist für mich net ganz nachvollziehbar allerdings auch etwas OT oder?
(Wenn ich es richtig verstanden habe).
Wenn man folgendes eingibt:

Code: Alles auswählen

foo.py *.txt
dann startet die Windows-Shell Dein Programm und übergibt das Argument '*.txt'. Eine vernünftige Shell expandiert das schon vor dem Aufruf, dass heisst Dein Programm bekommt alle Dateinamen die mit '.txt' enden als Argumente übergeben.

Das ist die praktischere Lösung weil man so nicht in *jedes* einzelne Programm Code einfügen muss, der diese Expansion vornimmt, sondern einfach nur Programme schreiben muss, die beliebig viele Dateinamen als Argumente bekommen. Damit fällt in Programmen auch die Sonderbehandlung weg, dass die Dateien in einem ganzes Verzeichnis bearbeitet werden sollen. Dafür ruft man das Programm einfach mit 'verzeichnisname/*' auf und die Shell sorgt dafür das alle Dateinamen in dem Verzeichnis übergeben werden.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Aaachso :)


Aber das könnte man doch mit einer "vorgestellten Funktion" ausfiltern oder? Diese übergibt dann die Argumente unbestimmter Form an die Hauptfunktion.

Aber nu jo.
Danke für die Aufklärung.


Nur so nebenbei. Wenn ich noch etwas weiterkomme dann gibet heute abend eine halbwegs funktionierende Version.
Mal schauen. :D


MFG EnTeQuAk
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

So ich habe mir mal die Libary angesehen und das Modul '' getopt '' gefunden.

Habe mal folgendes geschrieben:

Code: Alles auswählen

#!G:\Server\Python\python.exe
# -*- coding: iso-8859-1 -*-

import os
import getopt
import sys



def dos2unix(filename):
    infile = file(filename, "rb")
    copyfile = file(filename + '~', "wb")
    copyfile.write(infile.read())
    outfile = tempfile.TemporaryFile()
    for line in infile:
        line = line.replace("\r\n", "\n")
        outfile.write(line)
    infile.close()
    infile = file(filename, "wb")
    outfile.seek(0)
    for line in outfile:
        infile.write(line)
    infile.close()
    outfile.close()


def unix2dos(filename):
    infile = file(filename, "rb")
    copyfile = file(filename + '~', "wb")
    copyfile.write(infile.read())
    outfile = tempfile.TemporaryFile()
    for line in infile:
        line = line.replace("\r\n", "\n")
        line = line.replace("\n", "\r\n")
        outfile.write(line)
    infile.close()
    infile = file(filename, "wb")
    outfile.seek(0)
    for line in outfile:
        infile.write(line)
    infile.close()
    outfile.close()

def get_dir_file(opt, value):
    if opt in ('-d', '--dir'):
        dirrectory = value
        oneFile = None
    elif opt in ('-f', '--file'):
        oneFile = value
        dirrectory = None
    else:
        print 'Please use one of the follow arguments:  --file=FILENAME  or --dir=DIRNAME'
        print '\n\nSee the Help:\n'
        usage()
        sys.exit(2)

def usage():
    print 'Please give the follow arguments to the script'
    print '-dir /path/to/dir'
    print '-file /path/to/only/one/file!'
    print '-d2u    convert a DOS file to a Unix one'
    print '-u2d    convert a Unix file to a DOS one\n'
    print 'an example usage:'
    print
    print 'python converter.py  -u2d -dir /path/to/dir               - lets change all files in the dir from Unix ones to DOS'
    print 'python converter.py -d2u -file /path/to/file.txt          - lets change the coding of only one file from DOS to Unix'
    print

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', 'dir=DIRNAME','file=FILENAME', 'd2u', 'u2d'])
        if not opts and not args:
            print 'Keine Argumente!\n\n'
            usage()
    except getopt.GetoptError, msg:
        print 'GetOptError\n\n'
        print msg
        #usage()
        sys.exit(2)

        for opt, value in opts:
                if opt in ('-d2u'):
                    get_dir_file(opt=opt, value=value)
                    if dirrectory:
                        for files in dirrectory:
                            dos2unix(files)
                    if oneFile:
                        dos2unix(oneFile)
                elif opt in ('-u2d'):
                    get_dir_file(opt=opt, value=value)
                    if dirrectory:
                        for files in dirrectory:
                            unix2dos(files)
                    if oneFile:
                        dos2unix(oneFile)
                else:
                    print 'Please use one of the follow arguments! :   -d2u  -u2d  for more details see the -help !'
                    print '\n\nSee the Help:'
                    usage()
                    sys.exit(2)
                if opt in ('-h', '--help'):
                    usage()
                    sys.exit(2)

if __name__ == '__main__':
    main()

Funktioniert auch soweit alles.
(zumindest bis zu einem bestimmten Fehler)

Und zwar bei der Übergabe der Parameter.

Hier ein Beispiel:

Code: Alles auswählen

ente@Proggi-PC:~/Desktop$ python dos-unix-converter.py -u2d --file=svn
GetOptError


option -u not recognized
Ist es möglich, das er solche Argumente wie '' -u2d '' oder '' -d2u '' als zusammengehörig erkennt?

MfG EnTeQuAk
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

EnTeQuAk hat geschrieben:So ich habe mir mal die Libary angesehen und das Modul '' getopt '' gefunden.
Gut, dann such mal weiter, denn du findest auch das Modul optparse, welches neuer ist. Rebecca hat dir schon einmal in diesem Thread den Tipp gegeben:
Rebecca hat geschrieben:Uebrigens: Vielleicht waere das optparse-Modul was fuer dich.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Ohh :) ganz übersehen.


Na dann werde ich gleich mal nachschauen!
(bzw., wenn ich zu Hause bin :D)

Danke für den Hinweiß!
Auch an Rebecca! :D


MfG EnTeQUAk
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

EnTeQuAk hat geschrieben:Aber das mit den Newline Zeichen im Code ist wohl war.

das macht das ganze schwerer.
Dazu könntest du einfach line[:-2] und line[:-1] betrachten oder aber mit line.rstrip('\r\n') alle Umbrüche am Ende der Zeile entfernen (und das sollte durch den Loop nur maximal einer von jeder Sorte sein dürfen), worauf du dann die neuen, gewünschten Umbrüche wieder anhängen kannst.
Antworten