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

Code-Stücke können hier veröffentlicht werden.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Montag 20. November 2006, 16:02

Hm, wozu der ganze Aufwand? Unter Unixen gibt es oft die Scripte unix2dos und dos2unix, ansonsten sollte jeder gescheite, zum Programmieren geeignete Editor mit einem Klick das Konvertieren zwischen \n, \r und \r\n ermöglichen (z.B. SciTe).
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Montag 20. November 2006, 16:16

@Y0Gi:
Ist doch nicht schlecht und als Übung ganz gut.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Montag 20. November 2006, 17:20

So ich bin am umüberlegen.

Die Abfrage, ob er Benutzer überhaupt etwas angegeben hat, ist ja einfach ;)

Code: Alles auswählen

try:
    argv[1]
except IndexError:
    print 'Bitte ein Argument angeben  [weiteres folgt.... ;) ]'
Allerdings möchte ich schon gerne Kontrollieren könne, ob der Benutzer nun einen Pfad als Argument agegeben hat, eine einzelne Datei oder halt nicht.

Welche Kriterien könnte man da nehmen?

Da wären in meinen Augen nur:

Zur Unterscheidung, ob ein Pfad angegeben wurde das suchen nach " / ".
Oder nach einem " * ". da einzelne Dateien ja direkt angegeben werden.

Ich habe im Moment noch nicht so die Phantasie wie die Benutzung ablaufen soll. Mit Argumenten denke ich schon.
Allerdings würde ich halt die Möglichkeit der Umwandlung einzelner Dateien und ganzer Ordner bieten wollen.

Wenn es möglich ist auch gleich für MacOS. Fals das die Zeilenumbrüche anders speichern sollte. Das weiß ich allerdings nicht.

Freue mich auf Hilfen/Hinweise.

MfG EnTeQuAk
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Montag 20. November 2006, 17:33

Das ganze geht noch viel einfacher, wenn man die Dateien im "universal newline mode" öffnet. Dann konvertiert Python nämlich die Umbrüche automatisch in "\n".
BlackJack

Montag 20. November 2006, 20:59

EnTeQuAk hat geschrieben:Allerdings möchte ich schon gerne Kontrollieren könne, ob der Benutzer nun einen Pfad als Argument agegeben hat, eine einzelne Datei oder halt nicht.

Welche Kriterien könnte man da nehmen?

Da wären in meinen Augen nur:

Zur Unterscheidung, ob ein Pfad angegeben wurde das suchen nach " / ".
Man könnte auch einfach nachschauen ob es sich um eine Datei oder ein Verzeichnis handelt.
Oder nach einem " * ". da einzelne Dateien ja direkt angegeben werden.
Argh, da habe ich mal wieder nicht bedacht wie "braindead" Windows bzw. die Eingabeaufforderung dort ist. So ein * sollte von der Shell expandiert werden anstatt es jedem Anwendungsprogramm einzeln aufzubürden. Ich würde nur Dateinamen verarbeiten und Windowsbenutzern sagen, sie sollen gefälligst eine ordentliche Shell benutzen.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Dienstag 21. November 2006, 02:13

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:

Dienstag 21. November 2006, 08:34

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:

Dienstag 21. November 2006, 08:37

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

Dienstag 21. November 2006, 11:31

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:

Dienstag 21. November 2006, 11:42

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

Dienstag 21. November 2006, 11:48

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:

Dienstag 21. November 2006, 12:32

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

Dienstag 21. November 2006, 12:32

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:

Dienstag 21. November 2006, 12:37

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:

Mittwoch 22. November 2006, 04:44

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
Antworten