knoepel
Goto Top

Fortlaufende variable in batch möglich?

Hallo!

Folgende Situation:
Ich habe eine txt datei die nenn ich mal frosch0001.txt
Der Inhalt ist z.B:

Text
Text
Text
0001
Text

Jetzt möchte ich per batch die Zeile 0001 in eine fortlaufende Nummer ändern z.B. Bis 9999 und diese dann jedesmal in eine neue Datei ausgeben (frosch0001,frosch0002,...frosch9999).
Ich habe Bereits Lösungen gefunden, wie das zum erstellen einer Datei funktioniert. Aber noch nicht, wie man 9999 mit der passenden Änderung ausgibt.

Content-Key: 167669

Url: https://administrator.de/contentid/167669

Printed on: April 16, 2024 at 11:04 o'clock

Member: Friemler
Friemler Jun 08, 2011 at 10:46:39 (UTC)
Goto Top
Hallo Knoepel,

Deine Frage ist etwas schwer verständlich formuliert. Du willst also aus einer Datei 9999 Kopien erzeugen, die sich nur im Inhalt dieser einen Zeile und im Namen unterscheiden. Richtig soweit?

Ist 0001 denn wirklich der ganze Inhalt der Zeile? Das steht auch immer am Zeilenanfang? Gibt es in der Datei nur diese eine Zeile, die so oder nach dem gleichen Muster beginnt? Ist das immer (so wie im Beispiel) die 4. Zeile in der Datei? Können in der Datei Zeichen wie %, &, <, >, |, " oder ! vorkommen (das sind für Batchscripte Problemzeichen)?

Du musst schon etwas mehr Informationen liefern.

Gruß
Friemler
Member: Knoepel
Knoepel Jun 08, 2011 at 11:00:52 (UTC)
Goto Top
Ja, du hast das mit den 9999 Kopien richtig erkannt

Die 0001 steht immer so am Zeilenanfang ich könnte sie auch zum besseren wiederfinden in der Grundversion xxxx nennen damit es eine eindeutigkeit gibt.

Es nicht immer die vierte Zeile, diese variiert. Also muss die Zeile ausfindig gemacht werden.

Die von dir genannten Sonderzeichen sind nicht vorhanden. Nur ein paar : und ;
Member: Friemler
Friemler Jun 08, 2011 at 12:11:15 (UTC)
Goto Top
Hallo Knoepel,

probiere mal das hier:
@echo off

setlocal


set "SrcFileName=%~dpn1"  
set "SrcFileExt=%~x1"  

set "nCopies=10"  
set "nDigits=4"  
set "NumberMarker=xxxx"  


for /l %%i in (1,1,%nCopies%) do (
  for /f "eol=: tokens=1,* delims=:" %%k in ('findstr /n "^" "%SrcFileName%%SrcFileExt%"') do (  
    call :ProcessLine %%i
  )
)

exit /b



:ProcessLine
  set "Number=0000000000%~1"  
  call set "Number=%%Number:~-%nDigits%%%"  

  (for /f "delims=" %%d in ("DummyString") do (  
     echo\%%l|findstr /b /c:"%NumberMarker%" > NUL && (  
       echo %Number%
     ) || (
       echo\%%l
     )
  )) >>"%SrcFileName%%Number%%SrcFileExt%" 2>NUL  
exit /b

Das Icon der Ausgangsdatei mit der Maus auf das Icon des Batchfiles ziehen.

Die erzeugten Nummern fangen immer bei 0001 an. Den Endwert kannst Du über die Variable nCopies in Zeile 9 festlegen. Die Anzahl Stellen der erzeugten Zahl wird in Zeile 10 (hier 4) festgelegt. Die Kennung für die Zeile der Ausgangsdatei, in der in den Ausgabedateien die Zahl stehen soll, wird in Zeile 11 festgelegt.

Der Code ist etwas kompliziert, um evtl. doch vorhandene Sonderzeichen in der Ausgangsdatei fehlerfrei in die Zieldateien schreiben zu können.

Für Informationen zur FOR-Schleife bitte mein Tutorial zur FOR-Schleife durcharbeiten! In diesem Kommentar zum Tutorial von @jeb-the-batcher ist die Erklärung für die FOR-Schleife im Unterprogramm mit DummyString zu finden.

Gruß
Friemler


[EDIT]
Das Script schreibt jetzt auch Leerzeilen in die Zieldateien.
[/EDIT]
Member: Knoepel
Knoepel Jun 08, 2011 at 16:19:12 (UTC)
Goto Top
erstmal vielen Dank für deine Mühe!

Aber hast du das schon mal selbst getestet?
Ich finde den Prozess extrem langsam.
Hab hier nen 2x 1,6Ghz Rechner und der braucht pro Datei locker 30 Sek. Und bei 5000 Dateien.. oha...
Wie kommt das zustande?

Hab gerade noch was gefunden.
Wenn in der Datei Leerzeilen sind, werden die nicht mitkopiert. damit wird die Datei unbrauchbar.
Member: Friemler
Friemler Jun 08, 2011 at 16:40:19 (UTC)
Goto Top
Hallo Knoepel,

Batchscript ist kein Meister der Geschwindigkeit. Das Unterprogramm muss für jede Zeile jeder Datei aufgerufen werden, allein der Aufruf kostet schon Zeit und bei großen Dateien summiert sich das. Ich habe auf einem Intel Core i5 760 @ 4x2,8 GHz mit einer 5-Zeilen-Datei getestet, jede Zeile max. 10 Zeichen und davon 10 Kopien angelegt.

Nun ja, bei 30 Sekunden pro Datei würde das Script für 5000 Dateien knapp 2 Tage laufen face-sad . Da hilft dann wohl nur, das ganze in VBScript zu schreiben. Wenn ich zwischendurch noch Zeit finde, setze ich mich nochmal da ran.

Du hättest aber auch gleich erwähnen können, dass Du große Datenmengen verarbeiten willst...

...und von Leerzeilen war auch nicht die Rede. face-sad

Gruß
Friemler
Member: Friemler
Friemler Jun 08, 2011 at 18:33:18 (UTC)
Goto Top
Hallo Knoepel,

hier dann mal die VBScript-Version, die Deine Ansprüche an die Geschwindigkeit hoffentlich erfüllt. Die Bedienung erfolgt so, wie bei dem Batchscript.
Const nCopies      = 10
Const nDigits      = 4
Const NumberMarker = "xxxx"  


Const ForReading = 1
Const ForWriting = 2
Const AsASCII    = 0

If WScript.Arguments.Count > 0 Then
  Set objFSO = CreateObject("Scripting.FileSystemObject")  

  If objFSO.FileExists(objFSO.GetAbsolutePathName(WScript.Arguments(0))) Then
    strSrcFileName = objFSO.GetParentFolderName(objFSO.GetAbsolutePathName(WScript.Arguments(0)))
    strSrcFileName = strSrcFileName & "\" & objFSO.GetBaseName(WScript.Arguments(0))  
    strSrcFileExt  = "." & objFSO.GetExtensionName(WScript.Arguments(0))  

    Set objInFile  = objFSO.OpenTextFile(WScript.Arguments(0), ForReading, False, AsASCII)
    strFileContent = objInFile.ReadAll
    objInFile.Close

    arrLines = Split(strFileContent, vbCrLf)

    For I = 1 To nCopies
      strNumber = Right("0000000000" & CStr(I), nDigits)  

      Set objOutFile = objFSO.OpenTextFile(strSrcFileName & strNumber & strSrcFileExt, ForWriting, True, AsASCII)

      For J = 0 To UBound(arrLines)
        If arrLines(J) = NumberMarker Then
          objOutFile.WriteLine strNumber
        Else
          objOutFile.WriteLine arrLines(J)
        End If
      Next

      objOutFile.Close
    Next

    WScript.Quit 0
  End If

  WScript.Quit 2
End If

WScript.Quit 1

Bei fehlerfreier Ausführung hat die CMD-Variable %ERRORLEVEL% den Wert 0, wenn keine Datei als Parameter übergeben wurde den Wert 1 und wenn die Datei nicht existiert den Wert 2.

Gruß
Friemler
Member: Knoepel
Knoepel Jun 08, 2011 at 19:42:05 (UTC)
Goto Top
Ich sag nur WOW, das ist ja mal sehr viel schneller als das batchen! Saubere Arbeit!

Aber vbs ist für mich noch totales Neuland.

Ich hab das batch script wie folgt umgebaut:

echo Anzahl der auszugebenen Dateien
set /P "nCopies="

echo.
echo Anzahl der Stellen
set /P "nDigits="

echo.
echo Suchbegriff für Änderung
set /P "NumberMarker="

kann man so etwas auch ins vbs einbauen?
Member: Friemler
Friemler Jun 08, 2011 at 19:53:27 (UTC)
Goto Top
Hallo Knoepel,

dafür gibt es in VBS die InputBox. Beispiel:
Eingabe = InputBox("Machen Sie eine Eingabe.")

Lade Dir doch mal die Datei script56.chm, eine Sprachreferenz für VBS und JScript (bei Google suchen oder hier in deutsch runterladen).

Gruß
Friemler