Batch und Shell script um bestimmte Zeichen aus einer Datei in andere zu kopieren
Ich muss einige Simulationen durchführen und als Ergebnis werden jede menge Dateien erstellt. Darin sind aber nur bestimmte Werte von Interesse und die will ich nun nicht das kommende jahr Tag ein Tag aus manuell auslesen.
Also erstmal brauch ich das script sowohl in Batch(Für meinen Windows 7 Rechner) als auch in Shell (Für den Suse Linux Rechner, keine Ahnung welche version das ist bin erst vor ein paar tagen mit Linux in Berührung gekommen)
Das Umfeld sieht so aus:
Ich führe die Simulation durch(zu Hause am windows Rechner und auf der Arbeit am Linux Rechner) und dabei werden in einen Ordner jede Menge Dateien geschrieben die alle folgendes Aussehen haben:
wxxxryyy.avg
Wobei die xxx und die yyy durch Nummern ersetzt werden bei allen Dateien.
Das sind einfache Textdateien mit sehr viel Text, von Interesse sind aber nur bestimmte Stellen für mich.
Die Stellen sind immer die gleichen, aber es sind eben mehrere.
Im großen und ganzen soll das script also folgendes machen:
1. Eine Datei nach der anderen öffnen; wenn es geht dann in folgender reihenfolge:
w000r000.avg
w000r001.avg
w000r002.avg
.
.
.
w001r000.avg
w001r001.avg
w001r002.avg
.
.
.
Also die x-Werte sollen quasi die äusere Schleife bilden. Falls das nicht geht ist die Reihenfolge egal aber eben alle Dateien müssen geöffnet werden, dann sortier ich sie von Hand nach.
2. Ist die Datei offen mache folgendes:
2.1. gehe zu zeile x1 und zeichen y1. kopiere die nächsten z1 zeichen in eine datei namens tabelle.txt und mache einen tabulator sprung
2.2. gehe zu zeile x2 und zeichen y2. kopiere die nächsten z3 zeichen in eine datei namens tabelle.txt und mache einen tabulator sprung(rechts von 2.1. daher der tab)
2.3. gehe zu zeile x3 und zeichen y3. kopiere die nächsten z3 zeichen in eine datei namens tabelle.txt und mache einen tabulator sprung(rechts von 2.2. daher der tab)
.
.
.
Diesen Teil kann ich dann ja beliebig oft per copy und paste in die batch und shell ersetzen je nachdem wieviel Einträge ich benötige. Ob da nun am Ende ein extra tab drin ist ist auch egal.
3. Einmal ENTER drücken in der tabelle.txt und zur nächsten datei übergehen.
Das ist auch schon alles.
Am Ende sollen die ganzen Daten in der Tabelle.txt eben auch als Tabelle gespeichert werden wobei jede Zeile quasi der Inhalt einer Datei ist und die Spalten eben die herausgesuchten Einträge sind.
Ich habe gestern heute mal gegoogelt, es sind viele scripte da die ganze Zeilen kopieren aber ich habe nix gefunden was mehrere bestimmte Einträge in Tabellenform in eine andere Datei überträgt
Vielen dank im Vorraus
Also erstmal brauch ich das script sowohl in Batch(Für meinen Windows 7 Rechner) als auch in Shell (Für den Suse Linux Rechner, keine Ahnung welche version das ist bin erst vor ein paar tagen mit Linux in Berührung gekommen)
Das Umfeld sieht so aus:
Ich führe die Simulation durch(zu Hause am windows Rechner und auf der Arbeit am Linux Rechner) und dabei werden in einen Ordner jede Menge Dateien geschrieben die alle folgendes Aussehen haben:
wxxxryyy.avg
Wobei die xxx und die yyy durch Nummern ersetzt werden bei allen Dateien.
Das sind einfache Textdateien mit sehr viel Text, von Interesse sind aber nur bestimmte Stellen für mich.
Die Stellen sind immer die gleichen, aber es sind eben mehrere.
Im großen und ganzen soll das script also folgendes machen:
1. Eine Datei nach der anderen öffnen; wenn es geht dann in folgender reihenfolge:
w000r000.avg
w000r001.avg
w000r002.avg
.
.
.
w001r000.avg
w001r001.avg
w001r002.avg
.
.
.
Also die x-Werte sollen quasi die äusere Schleife bilden. Falls das nicht geht ist die Reihenfolge egal aber eben alle Dateien müssen geöffnet werden, dann sortier ich sie von Hand nach.
2. Ist die Datei offen mache folgendes:
2.1. gehe zu zeile x1 und zeichen y1. kopiere die nächsten z1 zeichen in eine datei namens tabelle.txt und mache einen tabulator sprung
2.2. gehe zu zeile x2 und zeichen y2. kopiere die nächsten z3 zeichen in eine datei namens tabelle.txt und mache einen tabulator sprung(rechts von 2.1. daher der tab)
2.3. gehe zu zeile x3 und zeichen y3. kopiere die nächsten z3 zeichen in eine datei namens tabelle.txt und mache einen tabulator sprung(rechts von 2.2. daher der tab)
.
.
.
Diesen Teil kann ich dann ja beliebig oft per copy und paste in die batch und shell ersetzen je nachdem wieviel Einträge ich benötige. Ob da nun am Ende ein extra tab drin ist ist auch egal.
3. Einmal ENTER drücken in der tabelle.txt und zur nächsten datei übergehen.
Das ist auch schon alles.
Am Ende sollen die ganzen Daten in der Tabelle.txt eben auch als Tabelle gespeichert werden wobei jede Zeile quasi der Inhalt einer Datei ist und die Spalten eben die herausgesuchten Einträge sind.
Ich habe gestern heute mal gegoogelt, es sind viele scripte da die ganze Zeilen kopieren aber ich habe nix gefunden was mehrere bestimmte Einträge in Tabellenform in eine andere Datei überträgt
Vielen dank im Vorraus
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 158102
Url: https://administrator.de/forum/batch-und-shell-script-um-bestimmte-zeichen-aus-einer-datei-in-andere-zu-kopieren-158102.html
Ausgedruckt am: 07.04.2025 um 03:04 Uhr
20 Kommentare
Neuester Kommentar

Auch dir eine Zeile des Grußes deiner Wahl.
Zum Bahnhof immer geradeaus und an der Kreuzung von x und z Achse links nach oben mit einem Tabulatorsprung zum Haupteingang.
Aus deinem Text kann man viel herauslesen, aber was du wirklich vorhast nicht.
btw:
Gruß
Zum Bahnhof immer geradeaus und an der Kreuzung von x und z Achse links nach oben mit einem Tabulatorsprung zum Haupteingang.
Aus deinem Text kann man viel herauslesen, aber was du wirklich vorhast nicht.
btw:
DIR /ON liefert die Namen sortiert aus von daher ist deine gewünschte Reihenfolge ein Kinderspiel, aber bis man drauf kommt ein Gedankenspiel - das "ich" niemandem, der "mir" potentiell helfen soll zumuten würde.
Gruß
Hallo linuxneuling!
Ich hab zwar keine Ahnung von Shell, aber ich versuch mich mal an der Batch-Version ...
Ist noch ungetestet - Bei Problemen schreib bitte rein was nicht tut.
Mathe172
Ich hab zwar keine Ahnung von Shell, aber ich versuch mich mal an der Batch-Version ...
@echo on & setlocal enabledelayedexpansion
set "Ordner=C:\Beispiel"
set "Tabelle=C:\Beispiel\Tabelle.txt"
set "x1=5"
set "y1=6"
set "z1=45"
REM ....
for /R "%Ordner%" %%A in (w???r???.avg) do (
REM Den letzten 1er durch die anzahl der Zahlentripel ersetzen
for /L %%B in (1,1,1) do (
set /a "a=!x%%B!-1"
set "b=!y%%B!"
set "c=!z%%B!"
for /F "usebackq delims=" %%C in ("%%A") do (
if not "!flag!"=="1" (
if "!a!" lss "1" (
set "Zeile=%%C"
call :ProcessLine
set "flag=1"
)
set /a "a -=1"
)
)
set "flag=0"
)
echo(!ZielZeile!>>"%Tabelle%"
set "ZielZeile="
)
:ProcessLine
REM Das am Ende vor dem " sollte ein Tab sein
set "ZielZeile=%ZielZeile%!Zeile:~%b%,%c%! "
goto :eof
Mathe172
moin,
hier noch eine etwas aussagkrätigere Variante
Ungetestet! müsste aber so gehen
Für die LinuxVersion eventuell:
Gruß Phil
hier noch eine etwas aussagkrätigere Variante
Ungetestet! müsste aber so gehen
@echo off&setlocal enabledelayedexpansion
:: nach Deinem Beispiel
:: gehe zu zeile 4
:: gehe zu zeichen 11
:: kopiere die nächsten 10 zeichen in den zwischenspeicher
:: gehe zu zeile 4
:: gehe zu zeichen 22
:: kopiere die nächsten 18 zeichen in den zwischenspeicher
:: Bedeutung.
:: "Z-zeilennummer:S-zähler für auszulesenden String je Zeile=Position des Zeichens,Stringlänge"
:: Beispiel: "Z-5:S-6=11,20" = Zeile 5; 6ter String; 11tes Zeichen; 20 Zeichenlang
:: Wenn max Zeile 10 auch eingelesen wird müssen entsprechende Vornullen geschrieben werden
:: dasselbe gilt auch für die stringanzahl
:: Beispiel: "Z-05:S-06=11,20"
:: Beispiel: "Z-15:S-12=50,2"
set "Z-4:S-1=11,20"
set "Z-4:S-2=22,18"
set "Ordner=C:\der mit den vielen Dateien"
set "Tabelle=C:\dort wo die Tabelle hinsoll\Tabelle.txt"
set "DateiFilter=w???r???.avg"
:begin
for /f "tokens=1,2* delims==," %%i in ('set Z-') do (
set /a Offset = %%j - 1
set "%%i=!Offset!,%%k"
)
pushD Ordner
(
for %%i in (%Dateifilter%) do (
set "NewLine="
for /f "delims=" %%j in ('findstr /n "^" %%i') do (
for /f "delims=:" %%k in ("%%j") do (
for /f "tokens=2 delims==" %%l in ('set Z-%%k 2^>nul') do (
set "Line=%%j"
set "Line=!Line:*:=!"
set "NewLine=!Line:~%%l! "
) ) )
if defined NewLine echo !NewLine!
)
)>"%Tabelle%"
popD
Für die LinuxVersion eventuell:
Zitat von @rallelin:
Sieht für mich aus, als wäre das ein Batch (call, goto usw.) - hilft mir in der Bash (#!/bin/bash) daher nur bedingt weiter. Mal schauen, ob ich das irgendwie angepasst bekomme...
Nachtrag (16.08.2010): Problem wurde mit einem zweiten Script "umgangen"; das Shell-Script arbeitet wie bisher und übergibt an ein gesondertes Perl-Script, welches über 'readdir' und 'rename' die noch ausstehende Aktion durchführt.
Sieht für mich aus, als wäre das ein Batch (call, goto usw.) - hilft mir in der Bash (#!/bin/bash) daher nur bedingt weiter. Mal schauen, ob ich das irgendwie angepasst bekomme...
Nachtrag (16.08.2010): Problem wurde mit einem zweiten Script "umgangen"; das Shell-Script arbeitet wie bisher und übergibt an ein gesondertes Perl-Script, welches über 'readdir' und 'rename' die noch ausstehende Aktion durchführt.
Gruß Phil
moin linuxneuling,
das war blos einTest ob Du die beiden Fehler selbst findest
mgreen
manchmal ist es ja ganz gut wenn man etwas Dabei Lernt oder?!
ich hab Zeile 30 und Zeile 39 dahingehend ausgebessert
in Zeile 30 habe ich die Prozentzeichen und doppelten Hochkammta um den VariablenNamen gelegt
in Zeile 39 habe ich !NewLine! auch nochmal exrta eingefügt.
es läuft jetzt also genau wie gewollt. Hier haste nochmal die Funktionstüchtige Batch
[Edit]
Hier stehen die Änderungen
[/Edit]
@mathe
das Kann Generell Kein Befehl machen, wenn die Verzögert aufgelösten Variablen - die Befehlsoptionen (welche den Befehl selbst beeinflussen) wären!
Verzögert aufgelöste Variablen werden ja direkt zur Ausführungszeit des Befehls Aufgelöst. Nicht beim Einlesen der BefehlsZeile- wenn ich falsch liege Bitte berichtigen.
Gruß Phil
das war blos einTest ob Du die beiden Fehler selbst findest
manchmal ist es ja ganz gut wenn man etwas Dabei Lernt oder?!
ich hab Zeile 30 und Zeile 39 dahingehend ausgebessert
in Zeile 30 habe ich die Prozentzeichen und doppelten Hochkammta um den VariablenNamen gelegt
in Zeile 39 habe ich !NewLine! auch nochmal exrta eingefügt.
es läuft jetzt also genau wie gewollt. Hier haste nochmal die Funktionstüchtige Batch
[Edit]
Hier stehen die Änderungen
[/Edit]
@echo off&setlocal enabledelayedexpansion
:: nach Deinem Beispiel
:: gehe zu zeile 4
:: gehe zu zeichen 11
:: kopiere die nächsten 10 zeichen in den zwischenspeicher
:: gehe zu zeile 4
:: gehe zu zeichen 22
:: kopiere die nächsten 18 zeichen in den zwischenspeicher
:: Bedeutung.
:: "Z-zeilennummer:S-zähler für auszulesenden String je Zeile=Position des Zeichens,Stringlänge"
:: Beispiel: "Z-5:S-6=11,20" = Zeile 5; 6ter String; 11tes Zeichen; 20 Zeichenlang
set "Z-4:S-1=11,20"
set "Z-4:S-2=22,18"
set "Ordner=C:\der mit den vielen Dateien"
set "Tabelle=C:\dort wo die Tabelle hinsoll\Tabelle.txt"
set "DateiFilter=w???r???.avg"
:begin
for /f "tokens=1,2* delims==," %%i in ('set Z-') do (
set /a Offset = %%j - 1
set "%%i=!Offset!,%%k"
)
pushD "%Ordner%"
(
for %%i in (%Dateifilter%) do (
set "NewLine="
for /f "delims=" %%j in ('findstr /n "^" %%i') do (
for /f "delims=:" %%k in ("%%j") do (
for /f "tokens=2 delims==" %%l in ('set Z-%%k: 2^>nul') do (
set "Line=%%j"
set "Line=!Line:*:=!"
set "NewLine=!NewLine!!Line:~%%l! "
) ) )
if defined NewLine echo !NewLine!
)
)>"%Tabelle%"
popD
@mathe
"!toskip! usebackq delims="" kann syntaktisch an dieser Stelle nicht verarbeitet werden.
kommt, weil eine Forschleife KEINE Verzögert aufgelösten Variablen in den "Analyseschlüsselwörter"n verarbeiten kann.das Kann Generell Kein Befehl machen, wenn die Verzögert aufgelösten Variablen - die Befehlsoptionen (welche den Befehl selbst beeinflussen) wären!
Verzögert aufgelöste Variablen werden ja direkt zur Ausführungszeit des Befehls Aufgelöst. Nicht beim Einlesen der BefehlsZeile- wenn ich falsch liege Bitte berichtigen.
Gruß Phil
Hallo,
@phil: Hab das Script jetzt umgeschrieben - es zählt einfach a runter bis 0 erreicht ist.
@linuxneuling: Kannst du bitte mal mein Script ausprobieren, mich würde interessieren obs jetzt funktionieren würde
Mathe172
@phil: Hab das Script jetzt umgeschrieben - es zählt einfach a runter bis 0 erreicht ist.
@linuxneuling: Kannst du bitte mal mein Script ausprobieren, mich würde interessieren obs jetzt funktionieren würde
Mathe172
moin mathe,
aber bist Du Garantiert NICHT!
bei Dir steckt gewiss noch eine Menge Potential drin. Das sollte gefördert werden, Vllt kannst Du dann mehr als ich - is ja egal - manchmal reicht nur ein passender Anstoss.
nach der Skatrunde und mehreren Bier Später werd ich dir mal ein bisscchen helfen.
in Zeile 10 schreibst Du noch ein REM ... was aber schnell von jemandem überlesen werden kann. - mach das Script so simpel wie möglich und fasse alle Eingaben am Anfang zusammen. Lass die Zählung doch eine ExtraZeile machen. zB.
dann schreibst Du in die Variable "a" die ZeilenNummer minus eins weniger - Du Vergleichst aber nirgendwo die Zeilennumer das geht nur wenn Du die For-Schleife der Zeile 15 so Gestaltest:
da Du aber nicht weisst, ob in der Datei am Zeilenanfang Doppelpunkte sind musst Du diese extra abtrennnen von der entstandenen ZeichenFolge und musst die Zeile 15 und folgende so schreiben.
somit hast Du in %%D die ZeilenNummer und in der Variable Zeile die gesamt Zeile drinstehen.
Du vergleichst zwar irgendetwas mit der Variable Flag aber im Grunde genommen geht dieser Vergleich nach der Zweiten Zeile jeder Datei ins Nirwana.
Gruß Phil
... (...bin ich ...)
schreib ich jetzt micht ausaber bist Du Garantiert NICHT!
bei Dir steckt gewiss noch eine Menge Potential drin. Das sollte gefördert werden, Vllt kannst Du dann mehr als ich - is ja egal - manchmal reicht nur ein passender Anstoss.
nach der Skatrunde und mehreren Bier Später werd ich dir mal ein bisscchen helfen.
in Zeile 10 schreibst Du noch ein REM ... was aber schnell von jemandem überlesen werden kann. - mach das Script so simpel wie möglich und fasse alle Eingaben am Anfang zusammen. Lass die Zählung doch eine ExtraZeile machen. zB.
for /f "delims=xyz=" %%i in ('set x^&set y ^&set z') do if !last! gtr %%i set "last=%%i"
for /F "tokens=1* delims=:" %%C in ("findstr /n "^" %%A") do (
for /F "delims=" %%C in ("findstr /n "^" %%A") do (
for /f "tokens=1* delims=:" %%D in ("%%C") do (
set "Zeile=%%C"
set "Zeile=!Zeile:*:=!"
Du vergleichst zwar irgendetwas mit der Variable Flag aber im Grunde genommen geht dieser Vergleich nach der Zweiten Zeile jeder Datei ins Nirwana.
Gruß Phil
Hallo Phil!
Zuerst mal Danke für die Tipps...
Ich hab jetzt mal das Script ein bisschen abgeändert, aber ich versteh noch nicht ganz was alle deine Schnippsel machen...
Das erste (for /f "delims=xyz=" %%i in ('set x^&set y ^&set z') do if !last! gtr %%i set "last=%%i") soll ja glaub ich selbstständig die Anzahl der Tripel finden, oder? (Dann muss man sie noch abändern, das "gtr" muss dann "lss" sein)
Das zweite bringt bei mir einen Syntaxfehler - mit dem würdest du die Zeilennummer rausfinden, oder?
Darf man das nicht so wie ich machen, bzw. ist es unschön? (Ich zähle a jede Zeile 1 runter und wenn es 0 ist, bin ich in der richtigen Zeile; Zeile 17 ind 22)
Beim dritten verstehe ich die letzte Zeile nicht so ganz. Das "!Zeile:*:=!" bedeutet doch, das alle Doppelpunkte mit etwas davor durch nichts ersetzt werden, oder?
Hier ist noch mal mein Code, mit deiner Hilfe jetzt mal in einem Punkt abgeändert und (ich hofffe) übersichtlicher gemacht
Nochmal Danke für die Tipps,
Mathe172
Zuerst mal Danke für die Tipps...
Ich hab jetzt mal das Script ein bisschen abgeändert, aber ich versteh noch nicht ganz was alle deine Schnippsel machen...
Das erste (for /f "delims=xyz=" %%i in ('set x^&set y ^&set z') do if !last! gtr %%i set "last=%%i") soll ja glaub ich selbstständig die Anzahl der Tripel finden, oder? (Dann muss man sie noch abändern, das "gtr" muss dann "lss" sein)
Das zweite bringt bei mir einen Syntaxfehler - mit dem würdest du die Zeilennummer rausfinden, oder?
Darf man das nicht so wie ich machen, bzw. ist es unschön? (Ich zähle a jede Zeile 1 runter und wenn es 0 ist, bin ich in der richtigen Zeile; Zeile 17 ind 22)
Beim dritten verstehe ich die letzte Zeile nicht so ganz. Das "!Zeile:*:=!" bedeutet doch, das alle Doppelpunkte mit etwas davor durch nichts ersetzt werden, oder?
Hier ist noch mal mein Code, mit deiner Hilfe jetzt mal in einem Punkt abgeändert und (ich hofffe) übersichtlicher gemacht
@echo off & setlocal enabledelayedexpansion
set "Ordner=C:\Ordner\"
set "Tabelle=C:\Ordner\Tabelle.txt"
set "x1=4"
set "y1=11"
set "z1=10"
REM ....
for /f "delims=x=" %%i in ('set x') do if "!last!" lss "%%i" set "last=%%i"
for /R "%Ordner%" %%A in (w???r???.avg) do (
for /L %%B in (1,1,%last%) do (
set /a "a=!x%%B!-1"
set "b=!y%%B!"
set "c=!z%%B!"
for /F "usebackq delims=" %%C in ("%%A") do (
if not "!flag!"=="1" (
if "!a!" lss "1" (
set "Zeile=%%C"
call :ProcessLine
set "flag=1"
)
set /a "a -=1"
)
)
set "flag=0"
)
echo(!ZielZeile!>>"%Tabelle%"
set "ZielZeile="
)
:ProcessLine
REM Das am Ende vor dem " sollte ein Tab sein
set "ZielZeile=%ZielZeile%!Zeile:~%b%,%c%! "
goto :eof
Nochmal Danke für die Tipps,
Mathe172
moin linuxneuling,
ja das wollte ich heute Früh noch hinschreiben, aber es waren dann doch ein paar Bier zu viel gewesen.
das ist ganz einfach:
in Zeile 36 steckte der Fehler: jetzt Zeile 32
da werden ja laut set Anweisung alle Variablen augegeben, welche zu Begin des VariableNamens mit "Z-ZeilenNummer" beginnen. Da die Zeile 10 am Anfang der ZeilenNummer auch eine EINS stehen hat wird auch die 1. Zeile verarbeitet - was nicht sein sollte.
Korrekt muss es heissen:
und das mit dem Vornullen in den VariablenNamen schreiben ist Quark (... was Interressiert mich mein Geschwätz von Gestern) die Zeile 01 könnte ja garnicht gefunden werden, weil Findstr /n "^" doch auch Keine Vornullen ausgibt.
ich Korregiere die Sachen mal oben
Gruß Phil
ja das wollte ich heute Früh noch hinschreiben, aber es waren dann doch ein paar Bier zu viel gewesen.
das ist ganz einfach:
in Zeile 36 steckte der Fehler: jetzt Zeile 32
for /f "tokens=2 delims==" %%l in ('set Z-%%k 2^>nul') do (
Korrekt muss es heissen:
for /f "tokens=2 delims==" %%l in ('set Z-%%k: 2^>nul') do (
ich Korregiere die Sachen mal oben
Gruß Phil
moin mathe,
hmmm - am besten ich erkläre Dir mal was Dein Code ab Zeile 09 macht.
09: Schreibe in die Variable last das was als größte Zeilenangabe in den Variablennamen (beginnend mit) xZEILE steht
10: Für jede entsprechende Datei des Musters w???r???.avg aus dem Verzeichnis C:\Ordner\ -Beginne eine Schleife 1 {was als eine BefehlsZeile gilt} und MERKE dir die Befehle der folgenden Zeilen
11: Zähle in EinerSchritten von 1 bis "Variable last" -mache für jede Zahl folgendes -Beginne eine Schleife 2 {was als eine BefehlsZeile gilt} und MERKE dir die Befehle der folgenden Zeilen
12: Schreibe in die Variable a das Ergebnis der Berechnung Variable xZahl minus eins
13: Schreibe in die Variable b die Variable yZahl
14: Schreibe in die Variable c die Variable zZahl
15: Für jede Komplett ausgelesene Zeile der entsprechenden Datei -Beginne eine Schleife 3 {was als eine BefehlsZeile gilt} und MERKE dir die Befehle der folgenden Zeilen
16: wenn die Variable flag nicht 1 ist -Beginne eine Schleife 4 {was als eine BefehlsZeile gilt} und MERKE dir die Befehle der folgenden Zeilen
17: wenn die Variable a kleiner als 1 ist -Beginne eine Schleife 5 {was als eine BefehlsZeile gilt} und MERKE dir die Befehle der folgenden Zeilen
18: Schreibe in die Variable Zeile die Komplett ausgelesene Zeile
19: gehe Zur Sprungmarke :ProcessLine und Öffne eine neue CMD-Instanz und Komm wieder wenn Du dort fertig bist
30: Sprungmarke :ProcessLine
31: Gib nach der Zeichenfolge REM (wenn ECHO ON) die folgenden Zeichen dieser Zeile aus: bis zu NICHT-Escapten bzw NICHT in doppelten Hochkommata stehenden
32: Schreibe in die Variable ZielZeile die Variable Zielzeile UND die Erweitert dargestellte Variable Zeile (vom Offset der Variable b und die folgende Anzahl Zeichen aus der Variable c) UND einen Tabulatoranschlag.
33: Beende diese CMD-Instanz
20: Schreibe in die Variable flag die Ziffer 1
21: Beende die aktuelle Schleife 5 {was als eine BefehlsZeile gilt} welche mit einer öffnende-Runde-Klammer Begonnen wurde - Führe die Befehle dieser Schleife aus!
22: Schreibe in die Variable a das Ergebnis der Berechnung Variable a minus eins
23: Beende die aktuelle Schleife 4 {was als eine BefehlsZeile gilt} welche mit einer öffnende-Runde-Klammer Begonnen wurde - Führe die Befehle dieser Schleife aus!
24: Beende die aktuelle Schleife 3 {was als eine BefehlsZeile gilt} welche mit einer öffnende-Runde-Klammer Begonnen wurde - Führe die Befehle dieser Schleife aus!
25: Schreibe in die Variable flag die Ziffer 0
26: Beende die aktuelle Schleife 2 {was als eine BefehlsZeile gilt} welche mit einer öffnende-Runde-Klammer Begonnen wurde - Führe die Befehle dieser Schleife aus!
27: Leite die Ausgabe, der auf diese CML-Line zu Schreibenden Zeile (mit dem Inhalt der Variable ZielZeile) als eine neue Zeile mit in die Datei "C:\Ordner\Tabelle.txt", um
28: Lösche die Variable ZielZeile
29: Beende die aktuelle Schleife 1 {was als eine BefehlsZeile gilt} welche mit einer öffnende-Runde-Klammer Begonnen wurde - Führe die Befehle dieser Schleife aus!
ab Zeile 11: ratterst Du durch die gesetzten xZahl Variablen und ratterst ab Zeile 15: für jede Zahl zeilenweise durch die entsprechende Datei
das dauert ja immens Lange wenn Du nur 10 auszuwertende Zeilen hast und die Datei hat 100 Zeilen, kommen insgesamt 1000 Lesezugriffe auf die Datei zu (jede Zeile 10x)
besser wäre Zeile 15: mit (Zeile 11: 13: 14: ) zu tauschen. Somit hast Du genau soviele Lesezugriffe auf die entsprechende Datei wie diese Zeilen enthält.
die Variable a müsste mit set /a a+=1 danach rein (Zeile 12: ) und mit Variable xZahl Zeile 17: Verglichen werden und in Zeile:10 gelöscht werden
die Variable flag würdest Du somit auch nicht mehr benötigen
der Offset des 1. Zeichens einer Variable ist 0 NICHT 1 - das müsstest Du noch runterechnen in der Variable b
wegen der Übersichtlichkeit
und wenn Du eine öffnende Klammer hast mach vor die folgenden Zeilen für jede offene Klammer 2 LeerZeichen am Zeilenanfang
wenn Du eine schliessende Klammer hast lässt Du je schliessende Klammer in dieser Zeile und Folgende Zeilen 2 LeerZeichen am Zeilenanfang weg
geht auch mit TAB anstatt 2 Leerzeichen
Gruß Phil
das "gtr" muss dann "lss" sein
sehr gut richtigDas zweite bringt bei mir einen Syntaxfehler - mit dem würdest du die Zeilennummer rausfinden, oder?
auch richtig. %%C ist die Zeilennummer und %%D ist der Inhalt der Zeile OHNE Führende Doppelpunkte am Zeilenbeginnfor /F "tokens=1* delims=:" %%C in ("findstr /n "^" %%A") do (
... Das "!Zeile:*:=!" bedeutet doch ...
Nein! Schau mal hier Erweitern von UmgebungsVariablenDarf man das nicht so wie ich machen, bzw. ist es unschön? (Ich zähle a jede Zeile 1 runter und wenn es 0 ist, bin ich in der richtigen Zeile; Zeile 17 ind 22)
hmmm - am besten ich erkläre Dir mal was Dein Code ab Zeile 09 macht.
@echo off & setlocal enabledelayedexpansion
set "Ordner=C:\Ordner\"
set "Tabelle=C:\Ordner\Tabelle.txt"
set "x1=4"
set "y1=11"
set "z1=10"
REM ....
for /f "delims=x=" %%i in ('set x') do if "!last!" lss "%%i" set "last=%%i"
for /R "%Ordner%" %%A in (w???r???.avg) do (
for /L %%B in (1,1,%last%) do (
set /a "a=!x%%B!-1"
set "b=!y%%B!"
set "c=!z%%B!"
for /F "usebackq delims=" %%C in ("%%A") do (
if not "!flag!"=="1" (
if "!a!" lss "1" (
set "Zeile=%%C"
call :ProcessLine
set "flag=1"
)
set /a "a -=1"
)
)
set "flag=0"
)
echo(!ZielZeile!>>"%Tabelle%"
set "ZielZeile="
)
:ProcessLine
REM Das am Ende vor dem " sollte ein Tab sein
set "ZielZeile=%ZielZeile%!Zeile:~%b%,%c%! "
goto :eof
10: Für jede entsprechende Datei des Musters w???r???.avg aus dem Verzeichnis C:\Ordner\ -Beginne eine Schleife 1 {was als eine BefehlsZeile gilt} und MERKE dir die Befehle der folgenden Zeilen
11: Zähle in EinerSchritten von 1 bis "Variable last" -mache für jede Zahl folgendes -Beginne eine Schleife 2 {was als eine BefehlsZeile gilt} und MERKE dir die Befehle der folgenden Zeilen
12: Schreibe in die Variable a das Ergebnis der Berechnung Variable xZahl minus eins
13: Schreibe in die Variable b die Variable yZahl
14: Schreibe in die Variable c die Variable zZahl
15: Für jede Komplett ausgelesene Zeile der entsprechenden Datei -Beginne eine Schleife 3 {was als eine BefehlsZeile gilt} und MERKE dir die Befehle der folgenden Zeilen
16: wenn die Variable flag nicht 1 ist -Beginne eine Schleife 4 {was als eine BefehlsZeile gilt} und MERKE dir die Befehle der folgenden Zeilen
17: wenn die Variable a kleiner als 1 ist -Beginne eine Schleife 5 {was als eine BefehlsZeile gilt} und MERKE dir die Befehle der folgenden Zeilen
18: Schreibe in die Variable Zeile die Komplett ausgelesene Zeile
19: gehe Zur Sprungmarke :ProcessLine und Öffne eine neue CMD-Instanz und Komm wieder wenn Du dort fertig bist
30: Sprungmarke :ProcessLine
31: Gib nach der Zeichenfolge REM (wenn ECHO ON) die folgenden Zeichen dieser Zeile aus: bis zu NICHT-Escapten bzw NICHT in doppelten Hochkommata stehenden
33: Beende diese CMD-Instanz
20: Schreibe in die Variable flag die Ziffer 1
21: Beende die aktuelle Schleife 5 {was als eine BefehlsZeile gilt} welche mit einer öffnende-Runde-Klammer Begonnen wurde - Führe die Befehle dieser Schleife aus!
22: Schreibe in die Variable a das Ergebnis der Berechnung Variable a minus eins
23: Beende die aktuelle Schleife 4 {was als eine BefehlsZeile gilt} welche mit einer öffnende-Runde-Klammer Begonnen wurde - Führe die Befehle dieser Schleife aus!
24: Beende die aktuelle Schleife 3 {was als eine BefehlsZeile gilt} welche mit einer öffnende-Runde-Klammer Begonnen wurde - Führe die Befehle dieser Schleife aus!
25: Schreibe in die Variable flag die Ziffer 0
26: Beende die aktuelle Schleife 2 {was als eine BefehlsZeile gilt} welche mit einer öffnende-Runde-Klammer Begonnen wurde - Führe die Befehle dieser Schleife aus!
27: Leite die Ausgabe, der auf diese CML-Line zu Schreibenden Zeile (mit dem Inhalt der Variable ZielZeile) als eine neue Zeile mit in die Datei "C:\Ordner\Tabelle.txt", um
28: Lösche die Variable ZielZeile
29: Beende die aktuelle Schleife 1 {was als eine BefehlsZeile gilt} welche mit einer öffnende-Runde-Klammer Begonnen wurde - Führe die Befehle dieser Schleife aus!
ab Zeile 11: ratterst Du durch die gesetzten xZahl Variablen und ratterst ab Zeile 15: für jede Zahl zeilenweise durch die entsprechende Datei
das dauert ja immens Lange wenn Du nur 10 auszuwertende Zeilen hast und die Datei hat 100 Zeilen, kommen insgesamt 1000 Lesezugriffe auf die Datei zu (jede Zeile 10x)
besser wäre Zeile 15: mit (Zeile 11: 13: 14: ) zu tauschen. Somit hast Du genau soviele Lesezugriffe auf die entsprechende Datei wie diese Zeilen enthält.
die Variable a müsste mit set /a a+=1 danach rein (Zeile 12: ) und mit Variable xZahl Zeile 17: Verglichen werden und in Zeile:10 gelöscht werden
die Variable flag würdest Du somit auch nicht mehr benötigen
der Offset des 1. Zeichens einer Variable ist 0 NICHT 1 - das müsstest Du noch runterechnen in der Variable b
wegen der Übersichtlichkeit
und wenn Du eine öffnende Klammer hast mach vor die folgenden Zeilen für jede offene Klammer 2 LeerZeichen am Zeilenanfang
wenn Du eine schliessende Klammer hast lässt Du je schliessende Klammer in dieser Zeile und Folgende Zeilen 2 LeerZeichen am Zeilenanfang weg
geht auch mit TAB anstatt 2 Leerzeichen
Gruß Phil
Hallo Phil!
Danke für die Erklärung! Ich hab' jetzt mit deiner Hilfe (nochmals Danke) den Code ziemlich eingedampft (auf 20 Zeilen exkl. Bemerkungen) und optimiert (Weniger Schreibzugriffe).
Hier die fertige Version
Mathe172
Danke für die Erklärung! Ich hab' jetzt mit deiner Hilfe (nochmals Danke) den Code ziemlich eingedampft (auf 20 Zeilen exkl. Bemerkungen) und optimiert (Weniger Schreibzugriffe).
Hier die fertige Version
REM ----- Quellcode von Mathe172 mit viel Unterstützung von pieh-ejdsch ------
@echo off & setlocal enabledelayedexpansion
set "Ordner=%~dp0"
set "Tabelle=Tabelle.txt"
REM Str'LaufendeNummer'='Zeile'-'Offset','Länge'
set "Str1=1-0,6"
set "Str2=2-7,5"
REM ....
for /f "tokens=1 delims=Str=" %%i in ('set Str') do if "!last!" lss "%%i" set "last=%%i"
for /R "%Ordner%" %%A in (w???r???.avg) do (
set "ZeileNr=0"
for /F "usebackq delims=" %%B in ("%%A") do (
set /a "ZeileNr +=1"
for /F "tokens=2-4 delims==-," %%C in ('set Str') do (
if "%%C"=="!ZeileNr!" (
set "Zeile=%%B"
set "ZielZeile=!ZielZeile!!Zeile:~%%D,%%E! "
)
)
)
echo(!ZielZeile!>>"%Tabelle%"
set "ZielZeile="
)
Mathe172
Hallo zusammen,
Genau genommen betrifft diese Einschränkung nur FOR, IF und den REM-Befehl, weil diese bereits in der Phase2 komplett geparsed werden.
Sprich bei einem IF ist es nicht möglich den Komperator oder den /I switch verzögert aufzulösen, die Vergleichsargumente selbst klappen aber.
Bei einem REM ist nur "/?" davon betroffen.
[code]
IF /i !var1!==!var2! echo klappt
set switch=/i
if !switch! "A"=="A" echo FEHLER
set myComp=EQU
if "A" !EQU! "A" echo FEHLER[/code]
Wie gesagt betrifft das nur REM,IF und FOR, z.B. bei set klappt die verzögerte Erweiterung auch für die switches.
[code]
set switch=/a
set !switch! n=5+6
echo %n%
[/code]
Ergibt 11
Grüße
jeb
Zitat von @pieh-ejdsch:
@mathe
> "!toskip! usebackq delims="" kann syntaktisch an dieser Stelle nicht verarbeitet werden.
kommt, weil eine Forschleife KEINE Verzögert aufgelösten Variablen in den "Analyseschlüsselwörter"n
verarbeiten kann.
das Kann Generell Kein Befehl machen, wenn die Verzögert aufgelösten Variablen - die Befehlsoptionen (welche den Befehl
selbst beeinflussen) wären!
Verzögert aufgelöste Variablen werden ja direkt zur Ausführungszeit des Befehls Aufgelöst. Nicht beim Einlesen
der BefehlsZeile- wenn ich falsch liege Bitte berichtigen.
@mathe
> "!toskip! usebackq delims="" kann syntaktisch an dieser Stelle nicht verarbeitet werden.
kommt, weil eine Forschleife KEINE Verzögert aufgelösten Variablen in den "Analyseschlüsselwörter"n
verarbeiten kann.
das Kann Generell Kein Befehl machen, wenn die Verzögert aufgelösten Variablen - die Befehlsoptionen (welche den Befehl
selbst beeinflussen) wären!
Verzögert aufgelöste Variablen werden ja direkt zur Ausführungszeit des Befehls Aufgelöst. Nicht beim Einlesen
der BefehlsZeile- wenn ich falsch liege Bitte berichtigen.
Genau genommen betrifft diese Einschränkung nur FOR, IF und den REM-Befehl, weil diese bereits in der Phase2 komplett geparsed werden.
Sprich bei einem IF ist es nicht möglich den Komperator oder den /I switch verzögert aufzulösen, die Vergleichsargumente selbst klappen aber.
Bei einem REM ist nur "/?" davon betroffen.
[code]
IF /i !var1!==!var2! echo klappt
set switch=/i
if !switch! "A"=="A" echo FEHLER
set myComp=EQU
if "A" !EQU! "A" echo FEHLER[/code]
Wie gesagt betrifft das nur REM,IF und FOR, z.B. bei set klappt die verzögerte Erweiterung auch für die switches.
[code]
set switch=/a
set !switch! n=5+6
echo %n%
[/code]
Ergibt 11
Grüße
jeb