Dateiendungen umbenennen: zB alle *.txt in *.ini
-
Hallo,
ich muss ein Programm schreiben welches Dateien umbenennen kann, zum einen ganz einfach wie der "mv" Befehl unter Linux aber auch mit der Möglichkeit alle Dateien mit der selben Dateiendung eine neue Endung zu geben.
Also die Bedienung soll wie folgt sein:
./ren namealt.txt nameneu.txt
Das hab ich hingekriegt, war nicht so schwer.Aber das Beispiel mit der Dateiendung:
./ren *.txt *.ini
klappt nicht so einfach.Mein bisheriges Programm:
#ifdef __unix__ #include <unistd.h> #else #include <io.h> #endif #include <time.h> #include <stdio.h> int main (int argc, char **argv) { time_t t; struct tm * ts; t = time(NULL); ts = localtime(&t); FILE *log; if(argc!=3){ printf("ERROR: Parameterfehler!\n"); log = fopen("./log.txt","a+"); fprintf(log, "%sERROR: Parameterfehler\n", asctime(ts)); fclose(log); return 0; } else if(access(argv[1], 00) == -1) { printf("ERROR: %s nicht vorhanden!\n", argv[1]); log = fopen("./log.txt","a+"); fprintf(log, "%sERROR: %s nicht vorhanden\n", asctime(ts), argv[1]); fclose(log); return 0; } else if(access(argv[2], 00) != -1) { printf("ERROR: %s bereits vorhanden!\n", argv[2]); log = fopen("./log.txt","a+"); fprintf(log, "%sERROR: %s bereits vorhanden\n", asctime(ts), argv[2]); fclose(log); return 0; } else printf("%s benennt jetzt %s in %s um! :-)\n", argv[0], argv[1], argv[2]); rename(argv[1], argv[2]); log = fopen("./log.txt","a+"); fprintf(log, "%s%s wurde in %s umbenannt\n",asctime(ts), argv[1], argv[2]); fclose(log); return 0; }
Habe da auch noch eine Logdatei eingbaut und ein paar if's bei falscher Bedienung. Grundlegen ist aber eben diser Teil für mein Vorhaben verantwortlich:
rename(argv[1], argv[2]);
Wenn ich da jetzt als Parameter nameneu.txt namealt.txt übergebe klappts auch. Aber wenn ich *.txt *.ini übergebe kommt die Meldung dass die *.txt Datei nicht gefunden wurde. Sie existiert ja auch nicht, das Sternchen ist nur Platzhalter (Wildcard).
Jemand ne Idee ?
Und nochwas; Bei meiner Logdatei kommt immer automatisch ein Absatz nach dem Datum, sieht im Quellcode hier deswegen auch etwas seltsam aus:fprintf(log, "%s%s wurde in %s umbenannt\n",asctime(ts), argv[1], argv[2]);
Aber nach dem ersten %s welches ja asctime(ts) entpricht kommt automatisch eine neue Zeile. Notfalls kann ich damit leben da die log Datei eh nur otional ist aber mich störts ein bisschen
(Wollte nämlich pro Ereignis nur eine Zeile und nicht eine für Datum und eine für Ereignis.)
Und allgmein noch: Ich bin totaler noob was das ganze Programmien angeht und bin mir durchaus bewusst dass mein Programm noch "sauberer" sein könnte. Ich hab erstmal einfach drauflosprobiert und war schon froh dass es jetzt zumindest teilweise funktioniert
-
Du musst da aufpassen.
Unter *ix macht normalerweise die Shell die Wildcardersetzung.
Du würdest bei *.txt ein paar mehr Argumente in argv bekommen.Unter Windows passiert das nicht. Da musst du dann Funktionen von Windows benutzen.
-
Also eine Möglichkeit wäre (wenn auch keine schöne)
MoveFile("C:\\Text.txt","C:\\MeinText.html")
-
DirkB schrieb:
Unter *ix macht normalerweise die Shell die Wildcardersetzung.
Du würdest bei *.txt ein paar mehr Argumente in argv bekommen.Unter Windows passiert das nicht. Da musst du dann Funktionen von Windows benutzen.
Ja ich habe schon gemerkt dass unter Linux ich zB
./ren nameal*.txt nameneu.txt
eingebe kann und es einwandfrei funktioniert. Das Terminal hat dieses Feature ja eingebaut und übernimmt diesen Part dann. Unter Windows funktiniert das aber nicht.
In erster Linie muss es auch nur unter Linux funktioniueren.Was meinst du aber damit das ich mehr argumente in argv bekomme?? Verstehe grade nicht ob Du meinst ich muss mehr eingeben muss oder mein programm erhält bei *.txt mehr(=zviel) als parameter ?
TocToc schrieb:
Also eine Möglichkeit wäre (wenn auch keine schöne)
MoveFile("C:\\Text.txt","C:\\MeinText.html")
Damit ändere ich doch nur den Namen von Text.txt in meintext.txt oder? Den Befehl MoveFile unter C kenn ich jetzt nicht aber wenn wie im Linuxshell mv ist wäre das ja einfaches umbennenen. Das klappt ja bereits. Aber ich möchte zb zehn *.txt Dateien im verzeichnis alle auf einen schlag in *.ini umbennenen.
Habe den Befehl "MoveFile" eben ausprobiert. Egal ob unter Win oder Linux, es treten Kompilierungsehler auf weil scheinbar der Befehl "MoveFile" nicht existiert. Muss ich evtl eine weitere Bibliothek mit einbinden?
-
Alfex schrieb:
Was meinst du aber damit das ich mehr argumente in argv bekomme?? Verstehe grade nicht ob Du meinst ich muss mehr eingeben muss oder mein programm erhält bei *.txt mehr(=zviel) als parameter ?
Lass dir am Anfang vom Programm doch mal den Wert von
argc
und alle Elemente vonargv
ausgeben.
-
DirkB schrieb:
Alfex schrieb:
Was meinst du aber damit das ich mehr argumente in argv bekomme?? Verstehe grade nicht ob Du meinst ich muss mehr eingeben muss oder mein programm erhält bei *.txt mehr(=zviel) als parameter ?
Lass dir am Anfang vom Programm doch mal den Wert von
argc
und alle Elemente vonargv
ausgeben.Oh ja, ich bin doof
habe mir den Fehler ja selber eingebaut.
Hier mein Code:
#ifdef __unix__ #include <unistd.h> #else #include <io.h> #endif #include <stdio.h> int main (int argc, char **argv) { printf("%s\n%s\n%s\n%s\n%s\n", argv[1], argv[2], argv[3], argv[4], argv[5]); printf("Anzahl Parameter: %i\n", argc); if(argc!=3){ printf("ERROR: Parameterfehler!\n"); return 0; } else if(access(argv[1], 00) == -1) { printf("ERROR: %s nicht vorhanden!\n", argv[1]); return 0; } else if(access(argv[2], 00) != -1) { printf("ERROR: %s bereits vorhanden!\n", argv[2]); return 0; } else printf("%s benennt jetzt %s in %s um! :-)\n", argv[0], argv[1], argv[2]); rename(argv[1], argv[2]); return 0; }
(Der übersicht halber hab ich die logdatei weggelassen)
Und hier die Ausgabe:
alex@debian:~/Schreibtisch/cprog$ gcc ver.c -o ver alex@debian:~/Schreibtisch/cprog$ ./ver *.txt *.ini 32.txt 3.txt 44.txt 555.txt log.txt Anzahl Parameter: 8 ERROR: Parameterfehler! alex@debian:~/Schreibtisch/cprog$
Frage:
Ich hab ja jetzt nur die ersten 5 Parameter (bzw den allerersten also den 0ten hab ich weggelassen) ausgeben lassen. Gibts einen Weg wirklich alle auszugeben?
Also egal ob 5 der 500 dass alle ausgegeben werden?
-
Alfex schrieb:
Gibts einen Weg wirklich alle auszugeben?
Also egal ob 5 der 500 dass alle ausgegeben werden?Klar. Schleife die von 1 ... (argc-1) läuft.
-
hustbaer schrieb:
Alfex schrieb:
Gibts einen Weg wirklich alle auszugeben?
Also egal ob 5 der 500 dass alle ausgegeben werden?Klar. Schleife die von 1 ... (argc-1) läuft.
Danke für den Tipp! Einfacher als gedacht, aber mussste erstmal etwas tüfteln.
int main (int argc, char **argv) { printf("Anzahl Parameter: %i\n", argc); int i=0; while (i<=argc-1){ printf("Parameter Nummer %i: %s\n", i, argv[i]); i++; } }
Ergebnis:
alex@debian:~/Schreibtisch/cprog$ gcc schleife.c -o schleife alex@debian:~/Schreibtisch/cprog$ ./schleife 345.txt 44.log s hallo 123 46 ende Anzahl Parameter: 8 Parameter Nummer 0: ./schleife Parameter Nummer 1: 345.txt Parameter Nummer 2: 44.log Parameter Nummer 3: s Parameter Nummer 4: hallo Parameter Nummer 5: 123 Parameter Nummer 6: 46 Parameter Nummer 7: ende alex@debian:~/Schreibtisch/cprog$
Oder jetzt mit Wildcard:
alex@debian:~/Schreibtisch/cprog$ ./schleife *.txt Anzahl Parameter: 7 Parameter Nummer 0: ./schleife Parameter Nummer 1: 32.txt Parameter Nummer 2: 3.txt Parameter Nummer 3: 44.txt Parameter Nummer 4: 555.txt Parameter Nummer 5: log.txt Parameter Nummer 6: reogl.txt alex@debian:~/Schreibtisch/cprog$
So und jetz tüftel ich daran wie es weitergeht mit dem Umbenennen...
-
Alfex schrieb:
while (i<=argc-1){
In C schreibt man gewöhnlich
< grenze
Alsowhile (i<argc)
Das versteht jeder C-Programmierer sofort ohne Nachdenken.
-
Alfex schrieb:
ich muss ein Programm schreiben welches Dateien umbenennen kann, zum einen ganz einfach wie der "mv" Befehl unter Linux aber auch mit der Möglichkeit alle Dateien mit der selben Dateiendung eine neue Endung zu geben.
Alfex schrieb:
In erster Linie muss es auch nur unter Linux funktioniueren.
Hast Du kein
rename(1)
?
-
DirkB schrieb:
]In C schreibt man gewöhnlich
< grenze
Danke für den Hinweis!
Furble Wurble schrieb:
Hast Du kein
rename(1)
?Ich kann dir nicht ganz folgen?
Was meinst du damit?
-
Alfex schrieb:
Furble Wurble schrieb:
Hast Du kein
rename(1)
?Ich kann dir nicht ganz folgen?
Was meinst du damit?
Die Zahlen bei Manpages:
1. Executables
2. Systemfunktionen
3. Bibliotheksfunktionen
...Es ist ein bisschen merkwürdig, ein Programm schreiben zu wollen, das nicht mehr ist als ein Frontend für die System- bzw. Bibliotheksfunktion rename (also rename(2) bzw. rename(3)), wenn es bereits auf jedem Linuxsystem ein Programm namens rename geben sollte (also rename(1)), welches genau solch ein Frontend darstellt.
man: rename(2): Von dir benutzt; Linux-Kernelfunktion
man: rename(3): Das gleiche, nach einem etwas allgemeineren Standard
man: rename(1): Ein Programm, das es auf jedem Linuxsystem gibt und das genau das gleiche tut wie dein Programm, bloß viel besser. Rate mal, was das intern wohl benutzt.
-
Alfex schrieb:
Furble Wurble schrieb:
Hast Du kein
rename(1)
?Ich kann dir nicht ganz folgen?
Was meinst du damit?
man rename(1)
kannst du in der Konsole/Terminal oder bei Google eingeben.
Falls du die man-pages nicht kennst: https://de.wikipedia.org/wiki/Manpage
-
Der praktische Hintergrund ist leider nicht vorhanden, das stimmt ...
Ich verstehe auch dass ihr mir daher andere Lösungswege nahelegt, ich soll zu Übungszwecken aber eben den Befehl "nachprogrammieren"