damorph
Goto Top

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?
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

Member: pieh-ejdsch
pieh-ejdsch Feb 06, 2012 at 09:17:40 (UTC)
Goto Top
moin DaMoRph,

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"  
[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
Member: DaMoRph
DaMoRph Feb 06, 2012 at 10:39:58 (UTC)
Goto Top
Ui, das ging ja fix.
kannst du mir das evtl. noch in Stichpunkten erläutern ?
das währe super.
Member: pieh-ejdsch
pieh-ejdsch Feb 06, 2012 at 11:37:58 (UTC)
Goto Top
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
Member: DaMoRph
DaMoRph Feb 06, 2012 at 14:04:35 (UTC)
Goto Top
Vilen dank schon mal für die Mühe,

ich habe das jetzt ausprobiert, aber es will nicht.
Die Batch erzeugt keine txt in dem anderen Ordner.
Und ich denke ich brauche den filter für den Namen der txt nicht denn die Batch kann bzw. soll alle Dateien die in dem Ordner sind bearbeiten.
Frage: der Parameter der den Wert für die zu löschende Zeile enthält, wie kann ich da mehrere werte hinzufügen? Denn es sin ja mehrere Zeilen die zu löschen sind.


mfg S.Meister
Member: bastla
bastla Feb 06, 2012 at 15:10:43 (UTC)
Goto Top
Hallo DaMoRph und willkommen im Forum!

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"  
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
Member: pieh-ejdsch
pieh-ejdsch Feb 06, 2012 at 18:11:25 (UTC)
Goto Top
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.
set "line=abcde"  
setlocal enabledelayedexpansion
(echo !line!)|findstr /n "^"  
endlocal
Umleitungen klappen aber immer --- Komisch.
In Jebs Die Geheimnisse des Batch Zeilen Interpreters ist es nicht aufgeführt oder daraus abzuleiten.

Gruß Phil
Member: bastla
bastla Feb 06, 2012 at 18:25:52 (UTC)
Goto Top
@ph
Deine funktioniert sogar.
Ja, ich war auch ganz erschrocken ... face-wink

Grüße
bastla
Member: rubberman
rubberman Feb 06, 2012 at 19:57:14 (UTC)
Goto Top
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
Member: pieh-ejdsch
pieh-ejdsch Feb 06, 2012 at 23:53:18 (UTC)
Goto Top
moin rubberman,

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
Member: rubberman
rubberman Feb 07, 2012 at 00:06:02 (UTC)
Goto Top
Hallo Phil.

Zitat von @pieh-ejdsch:
Wie lange läufst Du denn schon?
Och, so ca. seit 40 Jahren (meistens mit nächtlichen Unterbrechungen) face-wink

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 "^"  
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
Member: pieh-ejdsch
pieh-ejdsch Feb 07, 2012 at 08:29:32 (UTC)
Goto Top
moin rubberman,
na da lauf ich ja erst ca 34 Jahre herum face-wink 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
Member: bastla
bastla Feb 07, 2012 at 09:33:25 (UTC)
Goto Top
Hallo PH und rubberman!
Wieder einen Grund mehr VBS anzuwenden
Ich hab das mal als Auftrag verstanden face-wink:
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
Grüße
bastla
Member: DaMoRph
DaMoRph Feb 07, 2012 at 14:05:45 (UTC)
Goto Top
Hi zusammen,
ich bin eben erst wieder dazu gekommen es zu testen, ...und esl läuft super :D
Ich danke euch viel mals dafür.
Ich werde administrator.de gleich mal meinen Kollegen weiterempfehlen!

Aber eine Frage oder bitte habe ich noch, im Momment löschen wir das was Find findet.
Ist es auch umgekehrt möglich das wir alles aus der Datei löschen, bis auf die zeilen mit den bestimmten ziffern an stelle 4-7 ?

mfg S.Meister
Member: pieh-ejdsch
pieh-ejdsch Feb 07, 2012 at 14:54:03 (UTC)
Goto Top
moin DaMoRph,

natürlich - die Option /Vertausche Gefundenes mit Nicht gefundenem Ergebnis Weglassen.
die CMD-Hilfe help findstr gibt Dir immer Antworten.

Gruß Phil
Member: bastla
bastla Feb 07, 2012 at 15:00:11 (UTC)
Goto Top
... und im VBScript wäre die Zeile 15 auf
If InStr(Muster, "#" & Mid(Line, Entfernen + 1, Testen) & "#") <> 0 Then
zu ändern ...

Grüße
bastla
Member: DaMoRph
DaMoRph Feb 07, 2012 at 15:01:57 (UTC)
Goto Top
Hi,
ja super läuft, hätte aber eben nicht gedacht das ich nur den Parameter weg lassen muss face-smile


Vielen dank euch noch mal

mfg S.Meister