Per CMD: Suchen - Löschen - Bereinigen in Textdatei
Guten Tag, ich bin neu hier!
Oft schon habe ich hier begeistert mitgelesen und schon so manchen guten Code gefunden.
Jetzt aber ist es doch so speziell, daß ich selber posten will. Wenn es dafür eine Lösung gäbe, wäre das echt toll:
Eine per
dir *.* /A-D /S /OGN /B > C:\Obstlist.txt
erstellte Textdatei sieht (als Muster) beispielsweise zunächst so aus:
C:\Obst\Apfel.jpg
C:\Obst\Birne.jpg
C:\Obst\Dattel=01.jpg
C:\Obst\Dattel=02.jpg
C:\Obst\Dattel=03.jpg
C:\Obst\Dattel=04.jpg
C:\Obst\Kirsche.jpg
C:\Obst\Kiwi=Super.jpg
C:\Obst\Melone.jpg
C:\Obst\Pflaume=AAB.jpg
C:\Obst\Pflaume=AABCäsar.jpg
C:\Obst\Pflaume=Ferdinand.jpg
C:\Obst\Stachelbeere.jpg
...
und soll per cmdline (Batchbefehle)
mit diesem Ergebnis geändert werden:
C:\Obst\Apfel.jpg
C:\Obst\Birne.jpg
C:\Obst\Dattel=01.jpg
C:\Obst\Kirsche.jpg
C:\Obst\Kiwi=Super.jpg
C:\Obst\Melone.jpg
C:\Obst\Pflaume=AAB.jpg
C:\Obst\Stachelbeere.jpg
...
Beschreibung der Änderung:
Ein "=" im Dateinamen verweist auf eine fertig bearbeitete Datei mit evtl. mehreren Varianten. Zur Katalogisierung sind diese Varianten aber nicht erwünscht, sondern nur die alphabetisch jeweils erste Variante, die ein "=" enthält. Alle nachfolgenden Zeilen mit gleichem Dateinamen VOR dem "=" sollen gelöscht werden. Das Ergebnis wird wieder gespeichert unter C:\Obstlist.txt.
Das Programm sollte also dieses (oder ähnliches mit selbem Ergebnis) machen:
- Wenn in C:\Obstlist.txt
- die (alphabetisch von oben nach unten) nächste Zeile ein "=" enthält,
- dann nimm die Zeichenfolge vom Anfang dieser Zeile bis einschließlich zu dem "=",
- finde alle nachfolgenden Zeilen, die ebenso am Anfang genau diese Zeichenfolge enthalten,
- und lösche alle diese (nachfolgend gefundenen) Zeilen komplett.
- Fahre nun genauso fort mit der nächsten Zeile nach der eingangs gefundenen Zeile...
- Wenn fertig, speicheren.
Wie lautet der Batch-cmd-Code (Formel) für diese Aufgabe?
Warum? Der Job ist immer wieder zur Aktualisierung bei großen Dateilisten zu machen.
Vielen Dank!
Artemis
Oft schon habe ich hier begeistert mitgelesen und schon so manchen guten Code gefunden.
Jetzt aber ist es doch so speziell, daß ich selber posten will. Wenn es dafür eine Lösung gäbe, wäre das echt toll:
Eine per
dir *.* /A-D /S /OGN /B > C:\Obstlist.txt
erstellte Textdatei sieht (als Muster) beispielsweise zunächst so aus:
C:\Obst\Apfel.jpg
C:\Obst\Birne.jpg
C:\Obst\Dattel=01.jpg
C:\Obst\Dattel=02.jpg
C:\Obst\Dattel=03.jpg
C:\Obst\Dattel=04.jpg
C:\Obst\Kirsche.jpg
C:\Obst\Kiwi=Super.jpg
C:\Obst\Melone.jpg
C:\Obst\Pflaume=AAB.jpg
C:\Obst\Pflaume=AABCäsar.jpg
C:\Obst\Pflaume=Ferdinand.jpg
C:\Obst\Stachelbeere.jpg
...
und soll per cmdline (Batchbefehle)
mit diesem Ergebnis geändert werden:
C:\Obst\Apfel.jpg
C:\Obst\Birne.jpg
C:\Obst\Dattel=01.jpg
C:\Obst\Kirsche.jpg
C:\Obst\Kiwi=Super.jpg
C:\Obst\Melone.jpg
C:\Obst\Pflaume=AAB.jpg
C:\Obst\Stachelbeere.jpg
...
Beschreibung der Änderung:
Ein "=" im Dateinamen verweist auf eine fertig bearbeitete Datei mit evtl. mehreren Varianten. Zur Katalogisierung sind diese Varianten aber nicht erwünscht, sondern nur die alphabetisch jeweils erste Variante, die ein "=" enthält. Alle nachfolgenden Zeilen mit gleichem Dateinamen VOR dem "=" sollen gelöscht werden. Das Ergebnis wird wieder gespeichert unter C:\Obstlist.txt.
Das Programm sollte also dieses (oder ähnliches mit selbem Ergebnis) machen:
- Wenn in C:\Obstlist.txt
- die (alphabetisch von oben nach unten) nächste Zeile ein "=" enthält,
- dann nimm die Zeichenfolge vom Anfang dieser Zeile bis einschließlich zu dem "=",
- finde alle nachfolgenden Zeilen, die ebenso am Anfang genau diese Zeichenfolge enthalten,
- und lösche alle diese (nachfolgend gefundenen) Zeilen komplett.
- Fahre nun genauso fort mit der nächsten Zeile nach der eingangs gefundenen Zeile...
- Wenn fertig, speicheren.
Wie lautet der Batch-cmd-Code (Formel) für diese Aufgabe?
Warum? Der Job ist immer wieder zur Aktualisierung bei großen Dateilisten zu machen.
Vielen Dank!
Artemis
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 293871
Url: https://administrator.de/contentid/293871
Ausgedruckt am: 22.11.2024 um 13:11 Uhr
31 Kommentare
Neuester Kommentar
Hallo Artemis,
teste mal folgendes:
Gruß
Friemler
teste mal folgendes:
@echo off & setlocal
set "InFile=.\ObstListe.txt"
set "OutFile=.\ObstListe.txt"
set "TmpFile=%TEMP%\FilteredFileList.txt"
set "LastFile="
(for /f "usebackq tokens=* delims=" %%a in ("%InFile%") do (
for /f "tokens=1* delims==" %%b in ("%%~na") do (
call :ProcessFile "%%~dpa" "%%b" "%%~xa" "%%c"
)
)) > "%TmpFile%"
move "%TmpFile%" "%OutFile%" > NUL
exit /b 0
:ProcessFile
if "%~2" neq "%LastFile%" (
if "%~4" equ "" (
echo %~1%~2%~3
) else (
echo %~1%~2=%~4%~3
)
)
set "LastFile=%~2"
exit /b 0
Gruß
Friemler
Hallo Artemis,
als erstes fällt mir auf, dass Du eine veraltete Version des Scripts verwendest, die Deine Anforderungen nicht erfüllt. Kopiere Dir bitte den aktuellen Quelltext.
Zum Debuggen von Batchscripten sollte man
Dann sieht man die ausgegebenen Fehlermeldungen und kann außerdem den Scriptlauf verfolgen, d.h. man kennt die Stelle, an der das Script beendet wird.
Es könnte auch nützlich sein, den tatsächlichen Pfad zu Deiner
Zu Deiner Frage: "
Bei mir hier laufen übrigens beide Versionen des Scripts fehlerfrei.
Gruß
Friemler
als erstes fällt mir auf, dass Du eine veraltete Version des Scripts verwendest, die Deine Anforderungen nicht erfüllt. Kopiere Dir bitte den aktuellen Quelltext.
Zum Debuggen von Batchscripten sollte man
- diese immer aus einem Konsolenfenster starten und nicht per Doppelklick.
- das
@echo off
in der ersten Zeile entfernen oder durch::
bzw.REM
auskommentieren, dabei aber dassetlocal
in eine neue Zeile schreiben, damit es weiterhin ausgeführt wird.
Dann sieht man die ausgegebenen Fehlermeldungen und kann außerdem den Scriptlauf verfolgen, d.h. man kennt die Stelle, an der das Script beendet wird.
Es könnte auch nützlich sein, den tatsächlichen Pfad zu Deiner
HD-1.txt
zu kennen, evtl. enthält er irgendwelche Sonderzeichen, die das Script "verwirren". Auf jeden Fall wäre es eine gute Idee, bei Deinem DIR
-Befehl den Pfad zur Ausgabedatei in Anführungszeichen zu setzen, dann können darin enthaltene Sonder- und Leerzeichen an dieser Stelle schon nicht mehr stören.Zu Deiner Frage: "
.\
" ist eine Abkürzung für "Das aktuelle Verzeichnis".Bei mir hier laufen übrigens beide Versionen des Scripts fehlerfrei.
Gruß
Friemler
Hallo Artemis,
jo, evtl. solltest Du mal 'ne Mütze Schlaf nehmen, so viel Aufregung ist das nicht wert.
Das ist ein klassischer Fall von zu einfach strukturierten Beispieldaten. Die Ausgaberoutine, das Unterprogramm
Eine erste Entschärfung des Problems wäre folgendes:
Diese neue Version sollte mit sämtlichen abstrusen Zeichen in Dateinamen umgehen können.
In Zeile 4 kannst Du eine Dateimaske und in Zeile 5 das Trennzeichen einstellen.
Du kannst entweder eine Konsole in einem bestimmten Verzeichnis öffnen und von dort das Script starten (wird bei Dir ja über die
Das Script schaltet die verwendete Codepage in Zeile 24 auf ANSI um, damit normale Texteditoren und andere Programme in der erzeugten Ausgabedatei enthaltene deutsche Umlaute richtig darstellen bzw. lesen können. Falls Du die Ausgabedatei mit Batchscript weiterverarbeiten möchtest, musst Du Zeile 24 auskommentieren.
Deine neue Anforderung nach beliebigen Trennzeichen statt dem = lässt sich nicht so einfach erfüllen. Der Tokenizer der
Gruß
Friemler
jo, evtl. solltest Du mal 'ne Mütze Schlaf nehmen, so viel Aufregung ist das nicht wert.
Das ist ein klassischer Fall von zu einfach strukturierten Beispieldaten. Die Ausgaberoutine, das Unterprogramm
ProcessFile
, ist in ihrer obigen Form mit Dateinamen, die bestimmte Sonderzeichen enthalten, einfach überfordert - wir hantieren hier eben mit Batchscript, das nur sehr bedingt für die Verarbeitung von Text geeignet ist (und der Interpreter wurde wahrscheinlich von einem Redmonder Praktikanten geschrieben).Eine erste Entschärfung des Problems wäre folgendes:
@echo off & setlocal
:: ******* Begin Config *********
set "FileMask=*.txt"
set "Delim=="
set "InFile=C:\Katalog\HDD-1.txt"
set "OutFile=%InFile%"
:: ******** End Config **********
:: ----------- Init -------------
set "TmpFile=%TEMP%\FilteredFileList.txt"
set "LastFile="
:: Arbeitsverzeichnis setzen
if "%~1" neq "" cd /d "%~1"
:: Inhalt der evtl. bereits existierenden
:: temporären Datei löschen
type NUL > "%TmpFile%"
:: Codepage auf ANSI umschalten
chcp 1252 > NUL
:: ----------- Main -------------
:: Dateiliste erstellen
for %%a in ("%CD%") do (
if "%%~na" equ "" (
dir "%%~a%FileMask%" /s /b /a:-d /o:gne 2>NUL 1>"%InFile%"
) else (
dir "%%~a\%FileMask%" /s /b /a:-d /o:gne 2>NUL 1>"%InFile%"
)
)
:: Dateiliste verarbeiten
(for /f "usebackq tokens=* delims=" %%a in ("%InFile%") do (
for /f "tokens=1* delims=%Delim%" %%b in ("%%~na") do (
call :ProcessFileName
)
)) > "%TmpFile%"
:: Ausgabedatei erzeugen
move "%TmpFile%" "%OutFile%" > NUL
:: Script Ende
exit /b 0
:: -------- Unterprogramme ---------
:ProcessFileName
for /l %%x in (1,1,1) do (
if "%%b" neq "%LastFile%" (
if "%%c" equ "" (
echo %%~dpa%%b%%~xa
) else (
echo %%~dpa%%b%Delim%%%c%%~xa
)
)
set "LastFile=%%b"
)
exit /b 0
Diese neue Version sollte mit sämtlichen abstrusen Zeichen in Dateinamen umgehen können.
In Zeile 4 kannst Du eine Dateimaske und in Zeile 5 das Trennzeichen einstellen.
Du kannst entweder eine Konsole in einem bestimmten Verzeichnis öffnen und von dort das Script starten (wird bei Dir ja über die
PATH
-Variable gefunden) oder dem Script ein Verzeichnis als Parameter übergeben bzw. per Drag&Drop ein Verzeichnis auf dem Icon des Scripts "ablegen", das dann zum aktuellen Verzeichnis gemacht wird. In allen Fällen sucht das Script im dann aktuellen Verzeichnis nach Dateien, auf die die o.g. Maske passt. Damit es egal ist, ob es sich beim aktuellen Verzeichnis um das Wurzelverzeichnis eines Laufwerks oder um irgendein Unterverzeichnis handelt, habe ich die Konstruktion in den Zeilen 29 bis 35 eingebaut.Das Script schaltet die verwendete Codepage in Zeile 24 auf ANSI um, damit normale Texteditoren und andere Programme in der erzeugten Ausgabedatei enthaltene deutsche Umlaute richtig darstellen bzw. lesen können. Falls Du die Ausgabedatei mit Batchscript weiterverarbeiten möchtest, musst Du Zeile 24 auskommentieren.
Deine neue Anforderung nach beliebigen Trennzeichen statt dem = lässt sich nicht so einfach erfüllen. Der Tokenizer der
FOR
-Schleife behandelt eine Zeichenkette hinter delims=
als Liste von Trennzeichen. Bei delims=äß%
wären also ä, ß und % jeweils für sich alleine Trennzeichen, der Dateiname abcädef%ghißjkl.txt
würde also zerlegt zu abc
, def
, ghi
und jkl.txt
. Wenn Du als Trennzeichen irgendein chinesisches Zeichen angeben möchtest, wird das wahrscheinlich nicht funktionieren, da Du den Quelltext des Batchscripts (auf einem deutschen Windows) codiert mit der Codepage 850 abspeichern musst bzw. der Interpreter setzt dies voraus. Die Codepage 850 enthält aber keine chinesischen Zeichen, somit kannst Du diese auch nicht als Trennzeichen in den Quelltext eintragen. Sollte das eine wichtige Anforderung sein, kann man Batchscript nicht zur Lösung Deines Problems verwenden.Gruß
Friemler
Generelle Frage zum Forum-/ScriptHandling: Mein einkopiertes Script wurde nachträglich von Biber "in Form" gebracht. Hätte ich das selber tun sollen? Wie/wo steht/geht das? Andersherum: zum Besprechen ist das ja sehr praktisch und übersichtlich. Aber zum Anwenden muß ich erst kopieren, und dann aber (mühsam und fehlerträchtig) die ganzen Zeilenziffern und Leerzeichen zu Fuß löschen, damit das dann ein batchiges Gesicht bekommt. Oder wie wird das hier gehandhabt? Gibt es evtl. einen Geheimknopf, der mir Deinen Entwurf anwendungsgerecht runterlädt? Nur so eine Idee ...
Du hast schon ganz oben im Codebereich mal auf "Quelltext" geklickt, oder?
Und wenn du mal hier: Wie Du eine Frage richtig stellst nachliest, wirst du feststellen, dass es schon wünschenswert wäre, wenn du deine Beiträge entsprechend formatierst.
Beste Grüße!
Hallo Artemis,
freut mich, das Du etwas hast, mit dem Du arbeiten kannst. Deine Lösung mit den multiplen Dateimasken ist sehr interessant, diese Möglichkeit kannte ich auch noch nicht, zumindest nicht in der Form, dass bei jeder Maske immer der Pfad, der vor der ersten Maske angegeben wurde, verwendet wird.
Zu Deinen Fragen:
Die Dateiliste wird entweder mit der einen Methode (Zeile 31) oder mit der anderen (Zeile 33) erstellt. Zeile 31 wird in dem Fall benutzt, wenn das Arbeitsverzeichnis des Scripts das Wurzelverzeichnis eines Laufwerks ist. Ein
(was das Ergebnis von Zeile 33 in diesem Fall wäre) führt zu einer Fehlermeldung und zum Script-Abbruch. Deshalb fehlt in Zeile 31 der händisch hinzugefügte Backslash.
OK, das mit dem Trennzeichen hätte ich erklären müssen. Um zu erkennen, ob eine Datei in die Ausgabeliste aufgenommen werden soll, muss, laut Deiner Anforderung, der Namensteil vor dem Gleichheitszeichen/Trennzeichen der aktuellen Datei mit dem entsprechenden Namensteil der vorhergehenden Datei verglichen werden. Bei Ungleichheit wird die Datei in die Ausgabeliste aufgenommen.
Für das Splitting des Dateinamens dient die
Dieses Splitting per
Das Problem ist also: Ohne das Splitting des Dateinamens per
Ich denke mal, damit sind wir am Ende der Fahnenstange, besser geht es nicht mit Batchscript. Das ist sowieso schon mehr als das, wozu es eigentlich gedacht ist: Die Automatisierung von regelmäßig wiederkehrenden Aufgaben. Die Verarbeitung von Text war wohl eher nicht geplant.
Gruß
Friemler
[EDIT]
Btr. Trennzeichen: Bei Zeichen wie
[/EDIT]
freut mich, das Du etwas hast, mit dem Du arbeiten kannst. Deine Lösung mit den multiplen Dateimasken ist sehr interessant, diese Möglichkeit kannte ich auch noch nicht, zumindest nicht in der Form, dass bei jeder Maske immer der Pfad, der vor der ersten Maske angegeben wurde, verwendet wird.
Zu Deinen Fragen:
Die Dateiliste wird entweder mit der einen Methode (Zeile 31) oder mit der anderen (Zeile 33) erstellt. Zeile 31 wird in dem Fall benutzt, wenn das Arbeitsverzeichnis des Scripts das Wurzelverzeichnis eines Laufwerks ist. Ein
dir "E:\\*.txt"
OK, das mit dem Trennzeichen hätte ich erklären müssen. Um zu erkennen, ob eine Datei in die Ausgabeliste aufgenommen werden soll, muss, laut Deiner Anforderung, der Namensteil vor dem Gleichheitszeichen/Trennzeichen der aktuellen Datei mit dem entsprechenden Namensteil der vorhergehenden Datei verglichen werden. Bei Ungleichheit wird die Datei in die Ausgabeliste aufgenommen.
Für das Splitting des Dateinamens dient die
FOR
-Schleife in den Zeilen 40 bis 42. Diese Form der FOR
-Schleife (mit dem Parameter /f
) kann dazu benutzt werden, Zeichenketten anhand eines Trennzeichens bzw. einer Liste von Trennzeichen in sog. Tokens zu zerlegen (siehe dazu auch mein Tutorial zur FOR-Schleife).Dieses Splitting per
FOR
-Schleife ist in Batchscript die einzige Methode, bei der man den Dateinamen nicht in eine "normale" Batchscript-Variable (mit %
-Zeichen am Anfang und Ende, z.B. %FileMask%
) umspeichern muss. Denn nur beim Verarbeiten von FOR
-Laufvariablen (mit zwei %%
-Zeichen am Anfang, z.B. %%a
) wird der Inhalt der Variable nicht interpretiert. D.h. nur so lassen sich Deine Dateinamen mit Sonderzeichen verarbeiten und ausgeben. Deswegen habe ich im Unterprogramm ProcessFileName
nochmal eine FOR
-Schleife (for /l %%x in (1,1,1) do...
, läuft genau einmal durch) um die Vergleichs- und Ausgabebefehle "drumherum gewickelt". Durch diesen Trick kann ich die Laufvariablen der FOR
-Schleifen aus dem Hauptprogramm auch im Unterprogramm verwenden und die Probleme der ersten Script-Version lösen.Das Problem ist also: Ohne das Splitting des Dateinamens per
FOR
-Schleife lässt sich in Batchscript keine Lösung für Dein Problem finden. Daraus erwächst die Beschränkung, dass man nur eine einstellige Zeichenkette als Trennmarkierung definieren kann. Außerdem gelten für das Trennzeichen die üblichen Einschränkungen von Batchscript - es darf sich nicht um ein Zeichen handeln, das als Operator oder Befehl interpretiert werden kann, also zum Sprachumfang von Batchscript gehört (die Zeichen &%
hast Du ja selbst schon als solche identifiziert). Zugegeben, als Batchneuling hat man natürlich keine Ahnung, welche Zeichen das sein könnten, das musst Du eben durch Ausprobieren herausfinden.Ich denke mal, damit sind wir am Ende der Fahnenstange, besser geht es nicht mit Batchscript. Das ist sowieso schon mehr als das, wozu es eigentlich gedacht ist: Die Automatisierung von regelmäßig wiederkehrenden Aufgaben. Die Verarbeitung von Text war wohl eher nicht geplant.
Gruß
Friemler
[EDIT]
Btr. Trennzeichen: Bei Zeichen wie
&
könntest Du versuchen, sie zu "escapen", d.h. ein ^
voranzustellen. => aus &
wird ^&
[/EDIT]
Hallo Artemis,
als ich schrieb "Die Verarbeitung von Text war wohl eher nicht geplant." meinte ich die Designer/Entwickler des Batchscript-Interpreters, nicht Deine Aufgabenstellung.
Dein Text besteht aus Dateipfaden, also spreche ich auch davon. Ich bin da nicht "ins Dateimanagement abgerutscht".
Ich hatte Dir mit Version 2 des Scripts eine Luxusversion gebaut, die Du bequem in der von Dir geschilderten Umgebung (Script liegt in einem Verzeichnis, das in die
Das Script ist langsam, weil es für jeden Dateipfad aus Deiner Datei das Unterprogramm
So, das war jetzt mein letzter Kommentar zu der Sache - besser geht es nicht, da kannst Du Dich noch zehnmal beschweren. Wenn Du nicht zufrieden bist, versuche eben selbst eine Lösung zu finden. Es gibt außerdem auch noch VBScript. Das ist viel leichter erlernbar als Batchscript, weil es nicht aus einem Sumpf von Design- und Programmierfehlern besteht. Wenn Dir meine Erklärungsversuche zu hoch sind, dann glaube mir wenigstens, dass Deine Wünsche nach mehrstelligen beliebigen Trennzeichen nicht erfüllbar sind. Irgendwelches Optimierungspotenzial gibt es in Deiner eingedampften Scriptversion auch nicht.
Bzgl. "Nachträgliches Bearbeiten von Kommentaren": Rechts neben der Titelzeile jedes Kommentars, neben Datum und Uhrzeit, befindet sich der Link "Bearbeiten". Unter dem Kommentar gibt es rechts ein Menü (dargestellt durch 3 Punkte) neben dem Link für "Kommentieren", dort findest Du auch einen "Bearbeiten"-Link. Beide Links sind natürlich nur sichtbar, wenn Du im Forum eingeloggt bist.
Gruß
Friemler
als ich schrieb "Die Verarbeitung von Text war wohl eher nicht geplant." meinte ich die Designer/Entwickler des Batchscript-Interpreters, nicht Deine Aufgabenstellung.
Dein Text besteht aus Dateipfaden, also spreche ich auch davon. Ich bin da nicht "ins Dateimanagement abgerutscht".
Ich hatte Dir mit Version 2 des Scripts eine Luxusversion gebaut, die Du bequem in der von Dir geschilderten Umgebung (Script liegt in einem Verzeichnis, das in die
PATH
-Variable eingetragen ist; mit TotalCommander in ein Verzeichnis wechseln, dort eine Konsole öffnen und das Script starten) nutzen konntest. Jetzt hast Du es für den Produktiveinsatz auf das notwendigste eingedampft. Prima.Das Script ist langsam, weil es für jeden Dateipfad aus Deiner Datei das Unterprogramm
ProcessFileName
aufrufen muss. Dass ich hierfür ein Unterprogramm verwende liegt daran, dass ich mir den ersten Teil des Dateinamens (vor dem Trennzeichen) der aktuellen Datei für die Verarbeitung der nächsten Datei merken muss (die Zuweisung an die Variable %LastFileName%
). Um diese Zuweisung innerhalb der FOR
-Schleife im Hauptprogramm zu machen, müsste ich die verzögerte Variablenerweiterung aktivieren (darüber gibt es auch ein Kapitel in meinem Tutorial), was zu Problemen mit Dateipfaden führt, die ein Ausrufezeichen enthalten. Durch die Verwendung des Unterprogramms kann ich auch diese Klippe umschiffen, allerdings auf Kosten der Performance.So, das war jetzt mein letzter Kommentar zu der Sache - besser geht es nicht, da kannst Du Dich noch zehnmal beschweren. Wenn Du nicht zufrieden bist, versuche eben selbst eine Lösung zu finden. Es gibt außerdem auch noch VBScript. Das ist viel leichter erlernbar als Batchscript, weil es nicht aus einem Sumpf von Design- und Programmierfehlern besteht. Wenn Dir meine Erklärungsversuche zu hoch sind, dann glaube mir wenigstens, dass Deine Wünsche nach mehrstelligen beliebigen Trennzeichen nicht erfüllbar sind. Irgendwelches Optimierungspotenzial gibt es in Deiner eingedampften Scriptversion auch nicht.
Bzgl. "Nachträgliches Bearbeiten von Kommentaren": Rechts neben der Titelzeile jedes Kommentars, neben Datum und Uhrzeit, befindet sich der Link "Bearbeiten". Unter dem Kommentar gibt es rechts ein Menü (dargestellt durch 3 Punkte) neben dem Link für "Kommentieren", dort findest Du auch einen "Bearbeiten"-Link. Beide Links sind natürlich nur sichtbar, wenn Du im Forum eingeloggt bist.
Gruß
Friemler
Hallo zusammen,
Deswegen sollte man doch mal öfter mal einen Blick über den Tellerrand wagen und einer moderneren Skriptsprache wie Powershell eine Chance geben, wenn sich mit Ihr das ganze doch mit einem simplen Einzeiler erledigen lässt .
Welcher sich selbstverständlich auch mit minimalem Aufwand in eine Batch einbinden ließe:
Grüße Uwe
Es gibt außerdem auch noch VBScript. Das ist viel leichter erlernbar als Batchscript, weil es nicht aus einem Sumpf von Design- und Programmierfehlern besteht.
Da muss ich Friemler absolut zustimmen. DOS ist inzwischen in den "mit 50ern" angelangt und es wird so langsam aber sicher Zeit für die Rente Deswegen sollte man doch mal öfter mal einen Blick über den Tellerrand wagen und einer moderneren Skriptsprache wie Powershell eine Chance geben, wenn sich mit Ihr das ganze doch mit einem simplen Einzeiler erledigen lässt .
(gc 'c:\Obstlist.txt') | sort | group {$_.Split('=')} | %{$_.Group} | set-content 'C:\Obstlist.txt'
powershell.exe -ExecutionPolicy ByPass -Command "(gc 'c:\Obstlist.txt') | sort | group {$_.Split('=')} | %%{$_.Group} | set-content 'C:\Obstlist.txt'"
Da wird das Encoding deiner Datei wohl nicht erkannt worden sein, das lässt sich im CMDLet Get-Content(gc) zusätzlich als Parameter angeben. Funktioniert hier nämlich problemlos.
Man könnte hier auch Regular-Expressions für die Trennung einsetzen, dann hast du alle Möglichkeiten der Welt
Grüße Uwe
Man könnte hier auch Regular-Expressions für die Trennung einsetzen, dann hast du alle Möglichkeiten der Welt
Grüße Uwe
Zitat von @Artemis:
Also,
ich habe jetzt mal beide Skripte im Volleinsatz bei gleichen Bedingungen ("=") gegeneinander antreten lassen, das sind immerhin etwa 30.000 Textzeilen, und die Ergebnisse verglichen.
Tempo:
Skript Friemler ist mit 68 sec etwa 1/3 schneller als Skript Uwe mit 95 sec.
What ? Hier ist das Skript in 5 Sekunden fertig mit 50000 Zeilen generierter Pfade, was hast du für einen museumsreifen Rechner Btw. lässt sich das bei Bedarf auch noch beschleunigen wenn man möchte.Also,
ich habe jetzt mal beide Skripte im Volleinsatz bei gleichen Bedingungen ("=") gegeneinander antreten lassen, das sind immerhin etwa 30.000 Textzeilen, und die Ergebnisse verglichen.
Tempo:
Skript Friemler ist mit 68 sec etwa 1/3 schneller als Skript Uwe mit 95 sec.
Inhalt:
Skript Friemler hat etwa 20 Textzeilen weniger als Skript Uwe
??? Da hast du wohl unsere Skripte miteinander verwechselt mein Skript ist ein Einzeiler ...Skript Friemler hat etwa 20 Textzeilen weniger als Skript Uwe
Aber welche? Und warum?
Don't understand you ....Der Zufall hat mir aber dann eine verdächtige Stelle gezeigt. Endet ein Dateiname auf *=.* - also z.B. Februar=.jpg, was eine Vorauswahl, jedoch noch keine fertige Bearbeitung mit Varianten bedeutet, dann beläßt es Uwe genauso dabei, während Friemler in diesem Fall das "=" einfach wegmacht: Februar.jpg
Das wäre nun nicht weiter schlimm, wenn es da nicht manchmal noch andere Dateitypen von Februar gäbe, wie Februar.bmp und Februar.tif. Die fallen dann - logischerweise - bei Friemler gleich mit auf den Müll, während Uwe diese unangetastet läßt, genauso wie den routineauslösenden Februar=.jpg selbst.
Uwe sagt: Februar=.jpg gilt nur für jpg´s und sonst nüscht,
während Friemler das eher bayrisch löst: Komm..., weg damit, machts net so a G´schiss!
Im Ergebnis ist es ja egal, da es nur Einzelfälle sind.
Und unter dem Aspekt "Katalogisierung" ist die Friemler´sche Variante da sogar effektiver.
Fazit:
Wenn es bei der einfachen "="-Variante bleibt, schick ich Friemler ins Rennen.
Gibt es aber komplexere Bibliotheken zu katalogisieren, dann kann das nur Uwe übernehmen,
von dem ich evtl. noch ein paar Tricks zu einem erweiterten, logischeren Zeichensatz bekommen.
Wenn man alle deine Bedingungen kennen würde kann man auch auf alle reagieren und abfangen, wenn man sie vorher nicht kennt dann nicht Mit einem passenden Regex ist das ein Kinderspiel.Das wäre nun nicht weiter schlimm, wenn es da nicht manchmal noch andere Dateitypen von Februar gäbe, wie Februar.bmp und Februar.tif. Die fallen dann - logischerweise - bei Friemler gleich mit auf den Müll, während Uwe diese unangetastet läßt, genauso wie den routineauslösenden Februar=.jpg selbst.
Uwe sagt: Februar=.jpg gilt nur für jpg´s und sonst nüscht,
während Friemler das eher bayrisch löst: Komm..., weg damit, machts net so a G´schiss!
Im Ergebnis ist es ja egal, da es nur Einzelfälle sind.
Und unter dem Aspekt "Katalogisierung" ist die Friemler´sche Variante da sogar effektiver.
Fazit:
Wenn es bei der einfachen "="-Variante bleibt, schick ich Friemler ins Rennen.
Gibt es aber komplexere Bibliotheken zu katalogisieren, dann kann das nur Uwe übernehmen,
von dem ich evtl. noch ein paar Tricks zu einem erweiterten, logischeren Zeichensatz bekommen.
obwohl ich hier als Fachspezifischer Neuling antrete, fühle ich mich teils schnell an den Pranger gestell
Hmm, wo ? Ich sehe hier keinerlei provozierenden Aussagen, und Friemler und ich tun ja das mögliche deine mit jedem Post wachsenden Wünsche zu erfüllen, aber das geht eben nur wenn wir alle Bedingungen kennen die du stellst.Definiere also einfach nochmal ganz klar und knackig alle Bedingungen und Möglichkeiten deiner Namen und wie darauf reagiert werden soll, das geht leider aus obigen Aussagen noch nicht ganz klar hervor.
Dann ändere ich dir den Code entsprechend ab. Dann ist das hier mit zwei weiteren Posts geklärt und es braucht keine 20 weiteren Kommentare für so eine einfache Aufgabe.
Zu überdenken wäre ebenfalls auch mal eure jetzige Ablagestruktur der Files.
Merci.
Darum ging es mir nicht, es ging mir um die Rahmenbedingungen wann welches File als erstes definiert ist, und ob mit oder ohne andere Datei-Extension und ob das Gleichheitszeichen entfernt werden soll wenn es am Ende alleine steht etc.. Wenn man es anhand des Änderungsdatums ermitteln könnte ... das wäre ebenfalls kein Problem. Das Splitten selber ist kein Thema das kann ich dir problemlos so anpassen.
Wenn du nur das obige Skript mit anpassbarem Trennstring brauchst kannst du das hier nehmen:
Wo dein Trennstring hinkommt solltest du sehen können. Dort kannst du beliebige Zeichenfolgen verwenden, aber bitte immer nur Hochkommas um den String verwenden.
Wenn du nur das obige Skript mit anpassbarem Trennstring brauchst kannst du das hier nehmen:
(gc 'c:\Obstlist.txt') | sort | group {($_ -split [regex]::escape('=2='))} | %{$_.Group} | set-content 'C:\Obstlist.txt'
Du hast ja auch vergessen das Prozentzeichen der Foreach-Schleife zu verdoppeln wenn du die Powershell-Zeile in einer Batch verwendest. Siehe meine ersten Codes oben.
Und da deine Liste wie du schriebst schon sortiert ist kann der überflüssige Sortierschritt ebenfalls entfallen.
Aufruf
Btw. wenn du die Liste sowieso per Batch aus dem Dateisystem erzeugst, das ließe sich das auch ohne einen zusätzliche Zwischenschritt in eine Textdatei abfackeln und direkt in der Powershell machen, dann entfällt dieser unnötige Zwischenschritt.
Aufruf
Ansonsten den Beitrag dann bitte noch als gelöst markieren, du hast ja nun Input ein Masse und hast die Wahl. Merci.
Grüße Uwe
Und da deine Liste wie du schriebst schon sortiert ist kann der überflüssige Sortierschritt ebenfalls entfallen.
powershell -ExecutionPolicy Bypass -Command "(gc '%~1') | group {($_ -split [regex]::escape('%~2'))} | %%{$_.Group} | set-content '%~1'"
redu2.bat "C:\datei.txt" "==2=="
Btw. wenn du die Liste sowieso per Batch aus dem Dateisystem erzeugst, das ließe sich das auch ohne einen zusätzliche Zwischenschritt in eine Textdatei abfackeln und direkt in der Powershell machen, dann entfällt dieser unnötige Zwischenschritt.
powershell -ExecutionPolicy Bypass -Command "gci '%~1' -Recurse | ?{!$_.PSISContainer} | sort Fullname | group {$_.DirectoryName + '\' + ($_.Basename -split [regex]::escape('%~3'))} | %%{$_.Group.Fullname} | set-content '%~2'"
redu2.bat "C:\FolderToScan" "C:\datei.txt" "==2=="
Ansonsten den Beitrag dann bitte noch als gelöst markieren, du hast ja nun Input ein Masse und hast die Wahl. Merci.
Grüße Uwe
War nur ein Typo drin (Smartphone sei Dank ), ist korrigiert.
Und zur Info was die Tilde bei den Parametern bewirkt ist, dass bei Parametern eventuelle umschliessende Anführungszichen entfernt werden, solltest du mal einen Pfad mit Leerzeichen verwenden wollen.
Hoffe ich habe ein bisschen die Neugierde für die Powershell geweckt. Aber Achtung, wenn du einmal infiziert bist willst du kein Batch mehr sehen
So long
Grüße Uwe
Und zur Info was die Tilde bei den Parametern bewirkt ist, dass bei Parametern eventuelle umschliessende Anführungszichen entfernt werden, solltest du mal einen Pfad mit Leerzeichen verwenden wollen.
Hoffe ich habe ein bisschen die Neugierde für die Powershell geweckt. Aber Achtung, wenn du einmal infiziert bist willst du kein Batch mehr sehen
So long
Grüße Uwe