linuxneuling
Goto Top

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

Content-Key: 158102

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

Printed on: April 20, 2024 at 01:04 o'clock

Mitglied: 60730
60730 Jan 06, 2011 at 11:27:58 (UTC)
Goto Top
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:
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ß
Member: linuxneuling
linuxneuling Jan 06, 2011 at 12:26:01 (UTC)
Goto Top
Hallo,

OK dann verusch ich es nochmal anders zu formulieren.

In einem Ordner sind jede Menge Dateien die wie oben gesagt bennant werden.

Inhalt einer Datei sieht in etwa so aus:

aaaaaaaa bbbbbbbbbbbbbb ccccccccccccccccc
ssssssssssssss
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee rrrrrrrrrrrr ttttttttttttttttttt
oooooooooo uuuuuuuuuu llllllllllllllllll
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
kkkkkkkkkkkkkkkkkk ooooooooooooooooooooo
.
.
.

Also da ist wirklich eine Menge Zeug reingeschrieben. Das is halt die Ausgabe einer Simulation mit allen möglichen Ergebnisen und Parametern.

Einige dieser Parameter will ich nun in ein anderes Programm überführen damit ich es dort Zeichnerisch veranschaulichen kann. Dazu müssen aber die Werte in tabellarischer Form vorliegen(es werden X und y Werte in einem Koordinatensystem sein).

Alles was das Script also machen muss ist jede Datei öffnen und für jede Datei eine Zeile in der Tabelle.txt anlegen.
Pseudocode würde es etwa so aussehen:

Für i=1 bis maximum_x, i++ {
Für j=1 bis maximum_j, j++ {
Öffne Datei wiiirjjj.avg

gehe zu zeile 4
gehe zu zeichen 11
kopiere die nächsten 10 zeichen in den zwischenspeicher

Öffne Datei Tabelle.txt
kopiere inhalt aus zwischenspeicher in tabelle.txt
setze einen tabulator
Schliesse Datei Tabelle.txt

gehe zu zeile 4
gehe zu zeichen 22
kopiere die nächsten 18 zeichen in den zwischenspeicher

Öffne Datei Tabelle.txt
kopiere inhalt aus zwischenspeicher in tabelle.txt
setze einen tabulator
Schliesse Datei Tabelle.txt
}
Öffne Datei Tabelle.txt
drücke einmal ENTER
Schliesse Datei Tabelle.txt
}


Wenn es das durchgeführt hat mit obiger Datei sieht die Tabelle.txt so aus:
uuuuuuuuuu llllllllllllllllll


Ich hoffe es ist nun etwas verständlicher formuliert.

Mit freundlichen Grüßen
Member: mathe172
mathe172 Jan 06, 2011 at 15:18:37 (UTC)
Goto Top
Hallo linuxneuling!

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
Ist noch ungetestet - Bei Problemen schreib bitte rein was nicht tut.

Mathe172
Member: pieh-ejdsch
pieh-ejdsch Jan 06, 2011 at 17:56:22 (UTC)
Goto Top
moin,


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.


Gruß Phil
Member: linuxneuling
linuxneuling Jan 07, 2011 at 14:41:34 (UTC)
Goto Top
Hallo mathe172, und Hallo pieh-ejdsch

also ich hab dein (mathe172) programm ausprobiert, habe echo allerdings off gestellt weil er mir alles in das cmd fenster schreibt. Nachdem ich das getan habe kommt bei mir der fehler:

"!toskip! usebackq delims="" kann syntaktisch an dieser Stelle nicht verarbeitet werden.

Ich habe dann einfach mal das !toskip! rausgelöscht dann hat er die batch ausgeführt. und hat mir etwas in die tabelle geschrieben. Um es dann zu testen habe ich obige avg einfach mal erzeugt und dann folgenden code ausgeführt:

@echo off & setlocal enabledelayedexpansion
set "Ordner=D:\Test"
set "Tabelle=D:\Test\Tabelle.txt"
set "x1=4"
set "y1=11"
set "z1=10"
set "x2=4"
set "y2=22"
set "z2=18"
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,2) do (
set /a "a=!x%%B!-1"
set "b=!y%%B!"
set "c=!z%%B!"
if "!a!" geq "1" (set "toskip=skip=!a!") else (set "toskip=")
for /F " usebackq delims=" %%C in ("%%A") do (
if not "!flag!"=="1" (
set "Zeile=%%C"
call :ProcessLine
set "flag=1"
)
)
set "flag=0"
)
echo(!ZielZeile!>>"%Tabelle%"
)
:ProcessLine
REM Das am Ende vor dem " sollte ein Tab sein
set "ZielZeile=%ZielZeile%!Zeile:~%b%,%c%! "
goto :eof


als ausgabe habe ich dann jedoch bekommen:
w000r000.avg
aaaaaaaa bbbbbbbbbbbbbb ccccccccccccccccc
ssssssssssssss
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee rrrrrrrrrrrr ttttttttttttttttttt
oooooooooo uuuuuuuuuu llllllllllllllllll
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
kkkkkkkkkkkkkkkkkk ooooooooooooooooooooo

Tabelle. txt:
bbbbbbbbbb b cccccccccccccccc


Anscheinend nimmt er die x koordinate nicht an während er die y und z koordinaten nimmt.


_________________________________
_________________________________

So ich hab auch dein (pieh-ejdsch) Programm getestet. Dort bekomme ich als fehler "Das System kann den angegebenen Pfad nicht finden".
Die batch sieht so aus:

@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,10"
set "Z-4:S-2=22,18"
set "Z-1:S-3=22,5"

set "Ordner=D:\Test"
set "Tabelle=D:\Test\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

Mit der selben avg datei wie wieter oben erhalte ich dann als Tabelle.txt:
lllllllllllllllll

ändere ich den dritte "set" befehl zu "set "Z-5:S-3=2,5"" ist die ausgabe in der tabelle "mmmmm".
Anscheinend macht er keine tabulatoren und überschreibt immer wieder die ganze datei.


Mit freundlichen Grüßen
Member: pieh-ejdsch
pieh-ejdsch Jan 07, 2011 at 16:45:29 (UTC)
Goto Top
moin linuxneuling,

das war blos einTest ob Du die beiden Fehler selbst findest face-wink 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]

@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
Member: linuxneuling
linuxneuling Jan 07, 2011 at 16:58:56 (UTC)
Goto Top
Hallo Phil,

vielen vielen dank! Funktioniert super! Und nachdem ich heute schon die ersten 300 Dateien von Hand herausgeschrieben habe danken dir meine Hände auch!

Mit freundlichen Grüßen
Member: pieh-ejdsch
pieh-ejdsch Jan 07, 2011 at 17:05:50 (UTC)
Goto Top
wow 300 Dateien! Das bringt doch fast eine Tennisarm oder heisst das Tastaturgicht...?

[PS] kontest Du das Script in Linux schon einbinden?

Gruß Phil
Member: linuxneuling
linuxneuling Jan 07, 2011 at 17:17:37 (UTC)
Goto Top
Nein habe kein Linux bei mir zu Hause, kann also frühestens Montag schauen ob ich es hinbekomme

Mit freundlichen Grüßen
Member: mathe172
mathe172 Jan 07, 2011 at 18:23:13 (UTC)
Goto Top
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 face-smile

Mathe172
Member: linuxneuling
linuxneuling Jan 07, 2011 at 18:45:21 (UTC)
Goto Top
Hallo Mathe,

habs getestet, geht immernoch nicht face-smile

im moment ist die ausgabe so, dass die erste zeile/datei funktioniert. bei der zweiten datei wird aber der inhalt der ersten nochmal hingeschrieben und dann die der zweiten. und in der dritten zeile wird dann das von der zweiten und dann das von der dritten angehängt.

Mit freundlichen Grüßen
Member: mathe172
mathe172 Jan 07, 2011 at 19:02:33 (UTC)
Goto Top
Hallo Linuxneuling,

hab vergessen den Inhalt der Zeilen-ZwischenSpeicher-Variable zu leeren(...bin ich doof...)
Jetzt sollte es funktionieren.

Mathe172
P.S.:Danke fürs testen face-smile
Member: pieh-ejdsch
pieh-ejdsch Jan 08, 2011 at 00:50:34 (UTC)
Goto Top
moin mathe,

... (...bin ich ...)
schreib ich jetzt micht aus
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.
for /f "delims=xyz=" %%i in ('set x^&set y ^&set z') do if !last! gtr %%i set "last=%%i"
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:
for /F "tokens=1* delims=:" %%C in ("findstr /n "^" %%A") do ( 
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.
for /F "delims=" %%C in ("findstr /n "^" %%A") do (
	for /f "tokens=1* delims=:" %%D in ("%%C") do (
		set "Zeile=%%C"
		set "Zeile=!Zeile:*:=!" 
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
Member: linuxneuling
linuxneuling Jan 08, 2011 at 10:09:55 (UTC)
Goto Top
Hallo Phil,

kannst du dir deinen quellcode nochmal ansehen da ist ein ziemlicher fieser bug drin wo ich auch erstmal eine weile gebraucht habe um herauszufinden was passiert.

Wenn ich dem script sage es soll folgende ausgaben in die Tabelle schreiben:
set "Z-10:S-1=14,8"
set "Z-20:S-1=9,10"
set "Z-31:S-1=11,12"

Dann sieht die tabelle folgender masen aus:
Zeile1_von_Zeichen_14_8Stück Zeile2_von_Zeichen_9_10Stück Zeile3_von_Zeichen_11_12Stück Und_ab_hier_die_gewünschte_Ausgabe

In Worten erklärt:
Die erste Sache die er hinschreibt nimmt er aus Zeile 1 und nimmt dort die angegebenen Zeichen. Zeile eins deshalb weil doert Z-10 steht, also die 10er Stelle nimmt er
Dann nimmt er aus der Zeile 2 (weil dort Z-20) steht und nimmt die entsprechenden Zeichen
Dann nimmt er aus Zeile 3 (weil dort Z-31) steht und nimmt die entsprechenden Zeichen
(es ist nicht nur bei vollen 10ern Zeilen so habs auch mit 14, 25 etc probiert, kommt auch der bug)

Und dann kommt die korrekte Ausgabe hinterher, sprich dann kommt der Inhalt der Zeile 10,20,31. Ich habe also 6 Spalten anstelle von 3 und die ersten drei sind die verbuggten.

Achja und dieser S-1 Befehl hat keine auswirkung auf die Ausgabe in der Datei egal welche nummern ich da einfüge

Kannst du da was machen?

Mit freundlichen Grüßen
Member: mathe172
mathe172 Jan 08, 2011 at 10:34:11 (UTC)
Goto Top
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
@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
Member: pieh-ejdsch
pieh-ejdsch Jan 08, 2011 at 11:05:31 (UTC)
Goto Top
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
			for /f "tokens=2 delims==" %%l in ('set Z-%%k 2^>nul') do ( 
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:
			for /f "tokens=2 delims==" %%l in ('set Z-%%k: 2^>nul') do ( 
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
Member: linuxneuling
linuxneuling Jan 08, 2011 at 11:23:52 (UTC)
Goto Top
Morgen Phil,

vielen dank für die Verbesserung; funktioniert super. Hab nun auch herausgefunden wofür man die S-X Befehle braucht, wenn mehrere Sachen in einer Zeile sind geht es nur mit den S-X Befehlen!

Vielen dank nochmal!

Mit freundlichen Grüßen
Member: pieh-ejdsch
pieh-ejdsch Jan 08, 2011 at 14:53:10 (UTC)
Goto Top
moin mathe,

das "gtr" muss dann "lss" sein
sehr gut richtig
Das 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 Zeilenbeginn
for /F "tokens=1* delims=:" %%C in ("findstr /n "^" %%A") do ( 
... Das "!Zeile:*:=!" bedeutet doch ...
Nein! Schau mal hier Erweitern von UmgebungsVariablen

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)

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

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
Member: mathe172
mathe172 Jan 08, 2011 at 21:25:29 (UTC)
Goto Top
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

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
Member: jeb-the-batcher
jeb-the-batcher Jan 10, 2011 at 14:18:19 (UTC)
Goto Top
Hallo zusammen,

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.

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