Mehrere .txt mit Batch auslesen und verändern ?
Hallo zusammen,
ich möchte gerne eine Batch schreiben, habe aber feststellen müssen das meine Kenntnisse für diesen umfang nichtmehr ausreichen oder es mit einer Batch nicht evtl. garnicht geht...
Es geht darum dass ich in einen Ordner beliebige aber immer gleiche Art von Dateien kopiere für eine spätere Auswertung.
Diese Dateien haben einen nummerischen Namen Bsp. 101219246720.txt in dieser Datei gibt es ca. 27 Zeilen mit Alphanummerischen Werten,
wobei die ersten 3 die läge der Zeile angeben und nächsten 4 Ziffern immer angeben welcher wert dann kommt.
Ich möchte nun gerne mit dieser Batch bei allen Zeilen die ersten 3 Ziffern Löschen, die werden nicht benötigt.
Und dann alle Zeilen bis auf ca. 13 die dann mit den bestimmten Ziffer beginnen löschen.
Zudem gibt es in dem Ordner ca. 50 dieser txt. Immer andere nummerischer Name bei denen das passieren soll.
Ist das überhaupt mit einer Batch zu realisieren ?
Meine Idee war diese Werte mit Find zu suchen in eine neue Datei zu speichern, die alte zu löschen und diese neue dann in die alte umzubenennen aber ich scheiter da kläglich dran.
könnt ihr mir helfen?
Diese Dateien haben einen nummerischen Namen Bsp. 101219246720.txt in dieser Datei gibt es ca. 27 Zeilen mit Alphanummerischen Werten,
wobei die ersten 3 die läge der Zeile angeben und nächsten 4 Ziffern immer angeben welcher wert dann kommt.
Ich möchte nun gerne mit dieser Batch bei allen Zeilen die ersten 3 Ziffern Löschen, die werden nicht benötigt.
Und dann alle Zeilen bis auf ca. 13 die dann mit den bestimmten Ziffer beginnen löschen.
Zudem gibt es in dem Ordner ca. 50 dieser txt. Immer andere nummerischer Name bei denen das passieren soll.
Ist das überhaupt mit einer Batch zu realisieren ?
Meine Idee war diese Werte mit Find zu suchen in eine neue Datei zu speichern, die alte zu löschen und diese neue dann in die alte umzubenennen aber ich scheiter da kläglich dran.
könnt ihr mir helfen?
Please also mark the comments that contributed to the solution of the article
Kommentar vom Moderator Biber am Feb 06, 2012 um 20:40:32 Uhr
Nervigen Tippfehler im Titel berichtigt
Content-Key: 180075
Url: https://administrator.de/contentid/180075
Printed on: April 19, 2024 at 22:04 o'clock
16 Comments
Latest comment
moin DaMoRph,
also Ungetestet würde dies etwa so sein:
[edit] popD nachgezogen [/edit]
[edit2 usebackq nachgezogen ... und in die Richtige Zeile gesteckt/edit]
EDIT funktioniert doch nicht, da delayed Ausdrücke in mit Klammern zusammengefassten Befehlszeilen als nichtdelayed Ausdrücke im Übergebenen Befehl nicht automatisch delayed ausgegeben werden.
/EDIT
Gruß Phil
also Ungetestet würde dies etwa so sein:
@echo off &setlocal
set "Quelle=D:\Testordner"
set "Ziel=D:\Anderer Ordner"
set "DateiFilter=[0-9]*.txt"
set "ZeileLöschen=1234"
pushD "%quelle%"
for /f "delims=" %%i in ('dir /b *.txt ^|findstr /r /b "%DateiFilter%"') do call :Files "%%i"
popD
goto :eof
:Files
(
for /f "usebackq delims=" %%i in (%1) do (@set "Line=%%i"
@setlocal enabledelayedexpansion
@echo !Line:~3!
@endlocal
)
) | findstr /v /b "%ZeileLöschen%" > "%Ziel%\%~nx1"
[edit2 usebackq nachgezogen ... und in die Richtige Zeile gesteckt/edit]
EDIT funktioniert doch nicht, da delayed Ausdrücke in mit Klammern zusammengefassten Befehlszeilen als nichtdelayed Ausdrücke im Übergebenen Befehl nicht automatisch delayed ausgegeben werden.
/EDIT
Gruß Phil
hmmm, ich versuch es mal
also in
Zeile 2 und 3 bestimmst Du den Quellordner und den Zielordner.
In Zeile 5 bestimmt Du den Filter fürs Filtern der TXT Dateien (nur Ziffern vor der Dateiendung).
In Zeile 7 bestimmst Du den Filter fürs entfernen der Zeilen, weche ab dem 4. Zeichen diese Ziffern übereinstimmend enthalten.
In Zeile 9 wird in das Quellverzeichnis gewechselt.
In Zeile 10 werden alle TXT laut DateiFilter nacheinander dem Unterprogramm :Files als ersten Parameter Übergeben.
Nun SchauMaMal was das Unterprogramm macht:
In Zeile 14 sorgt die öffnende Klammer und die Schliessende Klammer von Zeile 20 für eine Gesamtausgabe der For Schleife.
In Zeile 15 bis 19 stelle ich fest die Option usebackq fehlt, um den Dateiinhalt abzuarbeiten
wird jede Zeile der übergebenen TXT ohne die ersten 3 Zeichen ausgegeben.
In Zeile 15 bis 18 sorgt das @ fürs ausblenden der Befehle, damit dem Findstr nur die reinen AusgabeZeilen übergeben werden.
In Zeile 20 werden die Zeilen nicht angezeigt, welche mit den Inhalt von ZeileLöschen beginnen und in eine TXT im Zeilordner eingefügt.
In Zeile 11 und 12 wird erst aus dem Quellverzeichnis wieder zurückgesprungen und anschliesend der Batch Beendet.
Gruß Phil
also in
Zeile 2 und 3 bestimmst Du den Quellordner und den Zielordner.
In Zeile 5 bestimmt Du den Filter fürs Filtern der TXT Dateien (nur Ziffern vor der Dateiendung).
In Zeile 7 bestimmst Du den Filter fürs entfernen der Zeilen, weche ab dem 4. Zeichen diese Ziffern übereinstimmend enthalten.
In Zeile 9 wird in das Quellverzeichnis gewechselt.
In Zeile 10 werden alle TXT laut DateiFilter nacheinander dem Unterprogramm :Files als ersten Parameter Übergeben.
Nun SchauMaMal was das Unterprogramm macht:
In Zeile 14 sorgt die öffnende Klammer und die Schliessende Klammer von Zeile 20 für eine Gesamtausgabe der For Schleife.
In Zeile 15 bis 19 stelle ich fest die Option usebackq fehlt, um den Dateiinhalt abzuarbeiten
wird jede Zeile der übergebenen TXT ohne die ersten 3 Zeichen ausgegeben.
In Zeile 15 bis 18 sorgt das @ fürs ausblenden der Befehle, damit dem Findstr nur die reinen AusgabeZeilen übergeben werden.
In Zeile 20 werden die Zeilen nicht angezeigt, welche mit den Inhalt von ZeileLöschen beginnen und in eine TXT im Zeilordner eingefügt.
In Zeile 11 und 12 wird erst aus dem Quellverzeichnis wieder zurückgesprungen und anschliesend der Batch Beendet.
Gruß Phil
Hallo DaMoRph und willkommen im Forum!
Wenn Du keinen Dateifilter benötigst, könntest Du es mit der folgende Variante versuchen:
Hier werden alle Zeilen entfernt, welche ab der 4. Stelle (deswegen jeweils die 3 Punkte davor) die Werte 1234 oder 0000 enthalten ...
Grüße
bastla
Wenn Du keinen Dateifilter benötigst, könntest Du es mit der folgende Variante versuchen:
@echo off & setlocal
set "Quelle=D:\Testordner"
set "Ziel=D:\Anderer Ordner"
set "ZeileLöschen=...1234 ...0000"
md "%Ziel%" 2>nul
pushD "%quelle%"
for /f "delims=" %%i in ('dir /b *.txt') do call :Files "%%i"
popD
goto :eof
:Files
(
for /f "delims=" %%i in ('findstr /v /b "%ZeileLöschen%" %1') do (
set "Line=%%i"
setlocal enabledelayedexpansion
echo !Line:~3!
endlocal
)
)>"%Ziel%\%~nx1"
Grüße
bastla
moin bastla,
Deine funktioniert sogar. Ich habe nicht getestet.
Ich dachte es geht - aber falsch gedacht. Abgesehen davon das das usebackq in der falschen For war und kein Zielverzeichnis erstellt wird wenn es fehlt.
Es wird nur der Text !Line:~3! in die TXT geschrieben.
Das kann ich mir nur so erklären, dass der Befehl in der Klammer immer ohne delayedexpansion mit den folgenden Verknüpft wird.
Umleitungen klappen aber immer --- Komisch.
In Jebs Die Geheimnisse des Batch Zeilen Interpreters ist es nicht aufgeführt oder daraus abzuleiten.
Gruß Phil
Deine funktioniert sogar. Ich habe nicht getestet.
Ich dachte es geht - aber falsch gedacht. Abgesehen davon das das usebackq in der falschen For war und kein Zielverzeichnis erstellt wird wenn es fehlt.
Es wird nur der Text !Line:~3! in die TXT geschrieben.
Das kann ich mir nur so erklären, dass der Befehl in der Klammer immer ohne delayedexpansion mit den folgenden Verknüpft wird.
set "line=abcde"
setlocal enabledelayedexpansion
(echo !line!)|findstr /n "^"
endlocal
In Jebs Die Geheimnisse des Batch Zeilen Interpreters ist es nicht aufgeführt oder daraus abzuleiten.
Gruß Phil
Hallo Phil,
auch dafür hatte jeb eine Erklärung, allerdings englisch ...
Why does delayed expansion fail when inside a piped block of code?
Stark vereinfacht: Beide Seiten der Pipe werden in ihrem eigenen Kommandozeilenkontext ausgeführt. Die verzögerte Variablenerweiterung wird dabei nicht vererbt. Ich hoffe, der verlinkte Thread trägt zum Verständnis bei.
Grüße
rubberman
auch dafür hatte jeb eine Erklärung, allerdings englisch ...
Why does delayed expansion fail when inside a piped block of code?
Stark vereinfacht: Beide Seiten der Pipe werden in ihrem eigenen Kommandozeilenkontext ausgeführt. Die verzögerte Variablenerweiterung wird dabei nicht vererbt. Ich hoffe, der verlinkte Thread trägt zum Verständnis bei.
Grüße
rubberman
moin rubberman,
Wie lange läufst Du denn schon?
Ja ist einleutend mit dem Pipen aber
da kamma ja Improvisieren...
auch
Wie lange läufst Du denn schon?
Ja ist einleutend mit dem Pipen aber
da kamma ja Improvisieren...
setlocal
set "line=abcdexxx"
set "line2=12345xxx"
set "linea=xyz123abc"
setlocal enabledelayedexpansion
(
echo !line!
echo !line2!
echo !linea!
)|findstr /n "^"
rem wenn das so nicht funktioniert dann bleibt ja als Variation fast nur das uebrig:
>Line.cmd (@echo @setlocal enabledelayedexpansion&@echo @echo(^^!Line%%~1%%~2%%~3%%~4%%~5%%^^!)
(
line :~3
line : "~3,-3"
line 2 ":*5="
line a : ~ 5
line a
)|sort|findstr /n "^"
call line 2 ":*3="
pause
auch
ganz erschrocken ...
Gruß Phil
Hallo Phil.
Och, so ca. seit 40 Jahren (meistens mit nächtlichen Unterbrechungen)
Für kürzere Sequenzen kannst du auch direkt die cmd mit den entsprechenden Optionen aufrufen.
Mehrere Zeilen eben per & verknüpfen, fertig.
Natürlich ist das Ganze grottenlangsam, für jede Zeile einmal cmd und findstr als externe Tools zu laden. Allerdings habe ich jetzt auch nicht DIE Lösung parat. Ich denke bastlas Code ist da ziemlich nah am Optimum, da findstr auf die Datei, nicht aber auf jede einzelne Zeile angewendet wird.
Grüße
rubberman
Och, so ca. seit 40 Jahren (meistens mit nächtlichen Unterbrechungen)
Für kürzere Sequenzen kannst du auch direkt die cmd mit den entsprechenden Optionen aufrufen.
set "line=abcde"
(cmd /q /v:on /c "echo(!line!")|findstr /n "^"
Natürlich ist das Ganze grottenlangsam, für jede Zeile einmal cmd und findstr als externe Tools zu laden. Allerdings habe ich jetzt auch nicht DIE Lösung parat. Ich denke bastlas Code ist da ziemlich nah am Optimum, da findstr auf die Datei, nicht aber auf jede einzelne Zeile angewendet wird.
Grüße
rubberman
moin rubberman,
na da lauf ich ja erst ca 34 Jahre herum meinte ja Dein Bildchen
Wieder einen Grund mehr VBS anzuwenden bzw weiter zu lernen.
Gruß Phil
na da lauf ich ja erst ca 34 Jahre herum meinte ja Dein Bildchen
Natürlich ist das Ganze grottenlangsam ... bastlas Code ist da ziemlich nah am Optimum.
sehe ich auch so - daher habe ich ja ganz oben den Roten Merker eingügt (und den nicht so funtionierenden Code so stehen gelassen,und weil es hier vollkommen unproduktiv ist).Wieder einen Grund mehr VBS anzuwenden bzw weiter zu lernen.
Gruß Phil
Hallo PH und rubberman!
Grüße
bastla
Wieder einen Grund mehr VBS anzuwenden
Ich hab das mal als Auftrag verstanden :Quelle = "D:\Testordner"
Ziel = "D:\Anderer Ordner"
Muster = "#1234#0000#8765#" 'weitere Suchbegriffe zum Entfernen von Zeilen hier - mit # begrenzt - hinzufügen
Entfernen = 3 'Zeichenanzahl, die am Zeilenanfang entfernt werden soll
Testen = 4 'Zeichenanzahl, die am Anfang der neuen Zeile geprüft werden soll
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(Ziel) Then fso.CreateFolder(Ziel)
For Each File In fso.GetFolder(Quelle).Files
TextAlt = Split(File.OpenAsTextStream.ReadAll, vbCrLf)
TextNeu = ""
For Each Line In TextAlt
If InStr(Muster, "#" & Mid(Line, Entfernen + 1, Testen) & "#") = 0 Then
TextNeu = TextNeu & vbCrLf & Mid(Line, Entfernen + 1)
End If
Next
'Die ersten beiden Zeichen in "TextNeu" stellen eine Zeilenschaltung dar und
' werden deshalb bei der Ausgabe übersprungen.
fso.CreateTextFile(Ziel & "\" & File.Name).Write Mid(TextNeu, 3)
Next
bastla