# BATCH - Zeilen- und Spaltenweise einlesen und ausgeben



## d-braun (10. November 2009)

Hi,

ich habe ein kleines Problem. Ich brauche ein Script dass mir zwei Dateien zusammenführt und den Inhalt der Dateien bearbeitet. Ziel ist es die zwei Dateien für einen Import vorzubereiten. Die zwei Dateien sehen wiefolgt aus:

Datei1:


> 01.01.2009;09:00;17,89;4;1;1
> 01.01.2009;09:12;21,13;4;1;1
> 01.01.2009;09:15;44,99;3;1;1



Datei2:


> 01.01.2009;09:15;44,99;3;2;1
> 01.01.2009;09:21;29,84;6;2;1



Aus diesen zwei Dateien soll eine Datei gemacht werden. Dabei muss jeweils der 5. Token einer Zeile angepasst werden. Als Ausgabe soll dann folgendes bei rauskommen:



> 01.01.2009;09:00;17,89;4;1;1
> 01.01.2009;09:12;21,13;4;1;1
> 01.01.2009;09:15;44,99;3;1;1
> 01.01.2009;09:15;44,99;3;1;1
> 01.01.2009;09:21;29,84;6;1;1



Folgendes habe ich bereits:

```
@echo off
COLOR 7
echo ==================================================
echo Exportdateien zusammenfuerhen
echo ==================================================
echo Welche Dateien wollen Sie zusammenfuehren?
:readfile1
set /p file1=Datei 1:
IF exist %file1% (
COLOR 7
echo OK
) ELSE (
COLOR C
echo !! Datei %file1% nicht gefunden !!
goto :readfile1
)
:readfile2
set /p file2=Datei 2:
IF exist %file2% (
COLOR 7
echo OK
) ELSE (
COLOR C
echo !! Datei %file2% nicht gefunden !!
goto :readfile2
)
echo Wie soll die erzeugte Datei heissen?
set /p outputname=Dateiname:
for /F "Tokens=5 delims=;" %%i in (%file1%) do set abteilung=%%i
* HIER MUSS DIE DATEI ZEILENWEISE AUSGELESEN WERDEN, DER 5. TOKEN GEÄNDERT WERDEN UND IN EINE DATEI GESCHRIEBEN WERDEN *
pause
```

Hier werden zunächst die beiden Dateien angegeben, der Name der Ausgabedatei festgelegt und die Referenznummer eingelesen auf welche der 5. Token geändert werden soll. Die Ausgabe in eine Datei ist auch kein Problem. Das bekomme ich mit

```
echo %var% >> %outputname%
```
hin. Jedoch weiß ich nicht wie ich es schaffe die Dateien zeilenweise durch zu gehen und jeweils die 5. Spalte zu ändern.

Ich hoffe jemand kann mir da weiter Helfen und nen kleinen Tipp geben. Ich bin im batchen leider nicht so fit.

Danke.


----------



## deepthroat (10. November 2009)

Hi.


```
for /f "tokens=1-5* delims=;" %i in (%datei%) do (
  @echo "%i;%j;%k;%l;NEUER WERT;%n"
)
```
Siehe "help for".

Gruß


----------



## d-braun (10. November 2009)

Hm das war ja einfach. Wusste nicht dass man einfach j, k, l etc. anhängen kann ohne diese zu definieren.

Danke für die schnelle Hilfe.


----------



## d-braun (13. November 2009)

Ok solange die einzelnen Werte gesetzt sind funktioniert das alles wuderbar. Allerdings kann es vorkommen dass eine Zeile keine Werte enthält. Dann würden die Dateien z.B. so aussehen:


> 02.11.2009;08:49;799,00;;20;1
> 02.11.2009;08:51;699,00;;20;1
> 02.11.2009;08:51;49,99;;70;1



D.h. der 4. Token wäre leer. In diesem Fall wird dieser Token einfach übersprungen und der nächste Token wird eingelesen. So wird aus


> 02.11.2009;08:49;799,00;;20;1





> %%i = 02.11.2009
> %%j = 08:49
> %%k = 799,00
> %%l = 20
> ...



anstelle von 



> %%i = 02.11.2009
> %%j = 08:49
> %%k = 799,00
> %%l =
> ...



Dies führt folglich zu einer falschen Ausgabe. Woran liegt das und wie kann ich das ändern?


----------



## deepthroat (13. November 2009)

d-braun hat gesagt.:


> Dies führt folglich zu einer falschen Ausgabe. Woran liegt das und wie kann ich das ändern?


Woran das liegt hast du selbst schon gesagt: aufeinanderfolgende Delimiter werden zusammengezogen. Dieses Verhalten läßt sich nicht ändern.

Aber du könntest die Zeilen verändern und vor der Verarbeitung alle aufeinanderfolgenden Semikola ersetzen:

```
for /f "tokens=*" %%l in (%datei%) do (
  set line=%%l
  set line=%line:;;=; ;%
  for /f tokens="1-5* delims=;" in ("%line%") do (
     ...
  )
)
```
Warum machst du das denn eigentlich mit einem Batch Skript? Perl oder AWK würden sich doch eher anbieten? Oder VBScript falls du nichts zusätzlich installieren kannst.

Gruß


----------



## d-braun (17. November 2009)

...

Ok vergesst am besten alles was ich hier mit nem Batch-Script versucht habe  Habs jetzt mit nem VBScript gelöst. Ist ja doch nicht soo schwer wie ich anfangs dachte und die Einarbeitungszeit hat sich auch in Grenzen gehalten.

Das Script liest nun ein komplettes Verzeichnis ein und ändert die ID's entsprechend ab. Hier das fertige Script:


```
' Deklaration der Variablen
Dim Ordner
Dim Pfad
Dim Filesystem
Dim Datei
Dim DateiName
Dim TextDatei
Dim TextDateiNeu
Dim NextLine
Dim Inhalt

' Ordner auswählen
Set Ordnerauswahl = CreateObject("Shell.Application").BrowseForFolder(0,"Ordner wählen",&H0001,16) 
If Ordnerauswahl Is nothing Then
    WScript.Quit
End If

' Pfad zum Ordner
Set Ordner = Ordnerauswahl.Self
Pfad = Ordner.Path

' Objekt erzeugen
Set Filesystem = CreateObject("Scripting.FileSystemObject")

' Ordner einlesen
Set Ordner = Filesystem.GetFolder(Pfad)

' Ausgabeordner erstellen
Set makedir = Filesystem.CreateFolder(Pfad & "\output") 

' Dateien einlesen
For Each Datei In Ordner.Files
	
	' Dateiname ermitteln
    DateiName = Datei.Nam
    
    ' Dateien öffnen
    Set TextDatei = Filesystem.OpenTextFile _
    (Datei, 1)
    Set TextDateiNeu = Filesystem.OpenTextFile _
    (Pfad & "\output\" & DateiName, 8, True)
    
    ' Dateien zeilenweise einlesen
    Do Until TextDatei.AtEndOfStream
        NextLine = TextDatei.Readline
        Inhalt = Split(NextLine , ";")
        For i = 0 to Ubound(Inhalt)
        
        	' Schreiben der Felder
            Select Case i
                Case 4
            
                	' Ändern der Abteilungs-IDs
                    Select Case Inhalt(i)
                        Case 1
                            TextDateiNeu.Write(5 & ";")
                        Case 2
                            TextDateiNeu.Write(5 & ";")
                        Case 13
                            TextDateiNeu.Write(1 & ";")
                        Case 15
                            TextDateiNeu.Write(3 & ";")
                        Case 16
                            TextDateiNeu.Write(1 & ";")
                        Case 17
                            TextDateiNeu.Write(2 & ";")
                        Case 18
                            TextDateiNeu.Write(2 & ";")
                        Case 70
                            TextDateiNeu.Write(8 & ";")
                        Case 80
                            TextDateiNeu.Write(8 & ";")
                        Case Else
                            TextDateiNeu.Write(Inhalt(i) & ";")
                     End Select
                     
                 Case 5
                     TextDateiNeu.WriteLine(Inhalt(i))
                 Case Else
                     TextDateiNeu.Write(Inhalt(i) & ";")
             End Select
             
        Next
    Loop
Next

' Ausgabe Erfolgsmeldung
msgbox("Dateien wurden erzeugt und in folgendem Ordner abgelegt: " & Pfad &"\output\")
```

Ein kleines Problemchen hab ich allerdings noch. Das Script lässt sich nicht kompilieren. Funktioniert zwar auch so aber als Exe wär das schon schöner. Auch in Hinsicht auf Veränderbarkeit.

Hab leider kein Visual Studio o.Ä. mit welchem ich das kompilieren kann.


----------

