seppae
Goto Top

Mit Batch in Bestimmter Zeilennummer Wert zu Zahl addieren

Hallo alle miteinander!

Ich habe folgende Aufgabenstellung bekommen und komme momentan einfach nicht weiter:
Ich soll in einer .txt datei nach dem String: SPA0 SPB90 SPC90 oder SPA0 SPB90 SPC180 suchen (es gibt noch mehr kombinationen)
und dann (das ist immer gleich) 2 Zeilen darüber, zum Wert der am ende der jeweiligen Zeile steht 0.03 dazuzählen. (ich weiß dass ich in Batch keine Kommazahlen dazurechnen kann,
aber vielleicht fällt hier jemanden ein Trick ein um dieses Problem zu lösen. (evtl auch mit anderer Programmiersprache)
Ich bin nun schon so weit, dass ich die Zeile ausfindig gemacht habe, in der ich den Wert ändern will.
Es geht also jetzt darum, den Wert zu addieren, und hier komme ich an die Grenzen meiner Fähigkeiten.


Auszug aus der zu ändernden Datei:
....
608 CYCL DEF 203 UNIVERSAL-BOHREN~
  Q200=2 ;SICHERHEITS-ABST.~
  Q201=-13 ;TIEFE~
  Q206=500 ;VORSCHUB TIEFENZ.~
  Q202=5 ;ZUSTELL-TIEFE~
  Q210=0 ;VERWEILZEIT OBEN~
  Q203=0 ;KOOR. OBERFLAECHE~
  Q204=22 ;2. SICHERHEITS-ABST.~
  Q212=0 ;ABNAHMEBETRAG~
  Q213=0 ;SPANBRUECHE~
  Q205=0 ;MIN. ZUSTELL-TIEFE~
  Q211=0 ;VERWEILZEIT UNTEN~
  Q208=25000 ;VORSCHUB RUECKZUG~
  Q256=0.25 ;RZ BEI SPANBRUCH
609 CALL LBL 7
610 * - T14 Tieflochbohren_03
611 CALL LBL 1
612 L Z-1 R0 F MAX M91
613 CYCL DEF 7.0 NULLPUNKT
614 CYCL DEF 7.1 X33.56
615 CYCL DEF 7.2 Y-35
616 CYCL DEF 7.3 Z-30.5
617 PLANE SPATIAL SPA0 SPB90 SPC-90 STAY SEQ+ TABLE ROT
618 L B+Q121 C+Q122 R0 F MAX M126
619 L X0 Y20 R0 F MAX
...

Hier in Zeile 617 SPA0 SPB90 SPC-90
und 2 Zeilen darüber müsste ich jetzt zu Y-35 0.03 dazuzählen,
und 3 Zeilen darüber von X33.56 0.05 wegzählen

Dies kommt etliche male in der Datei vor.
Wie gesagt die Zeile in der ich dies ändern müsste hab ich bereits ermittelt

Mein Codeschnipsel:
...
REM .
REM 0 90 -90x
REM .
for %%f in (C:\Users\faand.PROFIPACK3137\Desktop\michtest\kopie\%Datei%) do (
    for /F "tokens=1 delims=:" %%a in ('findstr /n /c:"SPA0 SPB90 SPC-90" %%f') do (  
        set var=%%a
	set /a var=var-3
        echo !var!
    )
) > "Treffer090-90x.txt"  

REM .
REM 0 90 -90y
REM .
for %%f in (C:\Users\faand.PROFIPACK3137\Desktop\michtest\kopie\%Datei%) do (
    for /F "tokens=1 delims=:" %%a in ('findstr /n /c:"SPA0 SPB90 SPC-90" %%f') do (  
        set var=%%a
	set /a var=var-2
        echo !var!
    )
) > "Treffer090-90y.txt"  
...

Hat jemand eine Idee wie ich das anstellen kann?
Vielen Dank im Voraus!
Mit freundlichen Grüßen Seppae

Content-ID: 282009

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

Ausgedruckt am: 25.11.2024 um 08:11 Uhr

114757
114757 04.09.2015, aktualisiert am 05.09.2015 um 17:10:45 Uhr
Goto Top
Moin,
ich würd das mit Powershell machen:
$file = 'C:\datei.txt'  
[regex]::Replace((gc $file | out-string),'(?sim)([\d\.\-]+)(\s*[^\r\n]*?)([\d\.\-]+)(\s*[^\r\n]*\s[^\r\n]*\s*[^\r\n]*)(SPA0 SPB90 SPC-90|SPA0 SPB90 SPC-180)',{  
param($m)
$g1 = [double]$m.Groups[1].Value - 0.05
$g2= $m.Groups[2].Value
$g3 = [double]$m.Groups[3].Value + 0.03
$g4 = $m.Groups[4].Value
$g5 = $m.Groups[5].Value
"$g1$g2$g3$g4$g5"  
}) | set-content $file
Gruß jodel32
Seppae
Seppae 04.09.2015 um 18:39:18 Uhr
Goto Top
Hallo Joedel32!

Danke für die schnelle Antwort.

Leider kenne ich mich mit Powershell null aus.
Kannst du mir deinen Code kurz erklären was du da genau machst.
Ist das bereits der ganze ablauf? (also suchen nach SPA0 SPB... und 2 bzw 3 Zeilen darüber den Wert addieren?

mfg Seppae
114757
114757 04.09.2015 aktualisiert um 18:48:50 Uhr
Goto Top
Zitat von @Seppae:
Kannst du mir deinen Code kurz erklären was du da genau machst.
Der Text wird per Regular-Expressions nach deinen Suchbegriffen durchsucht und per Group-Matching in einem Match-Evaluator werden die gewünschten Zahlen extrahiert, die gewünschten Werte hinzu addiert/subtrahiert und ersetzt. Das ganze wird dann zum Schluss wieder in die Original-Datei zurückgeschrieben.
Ist das bereits der ganze ablauf? (also suchen nach SPA0 SPB... und 2 bzw 3 Zeilen darüber den Wert addieren?
Yes, thats' all face-smile Du siehst wie mächtig die Power-Muschel ist ... und in jedem aktuellen Windows seit Vista enthalten.

Wie man Powershell-Skripte ausführt, liest du hier:
Powershell Skripte ausführen
Seppae
Seppae 04.09.2015 um 19:02:49 Uhr
Goto Top
Hätte da noch eine Frage (als Powershell Laie):
Wo genau springst du die 2 bzw die 3 Zeilen darüber um den wert auszulesen.
BZW wie kommst du da auf die Groups 1 und 3?
sind das einfach die Zahlen(Werte) die vor der gefundenen Zeile kommen?
Also 1. Wert vor dem Treffer ist Groups 1 usw?

mfg Seppae
114757
114757 04.09.2015 aktualisiert um 19:12:57 Uhr
Goto Top
Zitat von @Seppae:

Hätte da noch eine Frage (als Powershell Laie):
Wo genau springst du die 2 bzw die 3 Zeilen darüber um den wert auszulesen.
BZW wie kommst du da auf die Groups 1 und 3?
sind das einfach die Zahlen(Werte) die vor der gefundenen Zeile kommen?
Also 1. Wert vor dem Treffer ist Groups 1 usw?
Das vollständige erklären von Regular Expressions würde hier Jahre dauern ...
Wenn du es genau wissen willst:
Regular Expressions Tutorial
(?sim)([\d\.]+)(\s*[^\r\n]*?)([\d\.\-]+)(\s*[^\r\n]*\s[^\r\n]*\s*[^\r\n]*)(SPA0 SPB90 SPC-90|SPA0 SPB90 SPC-180)

Options: dot matches newline; case insensitive; ^ and $ match at line breaks

Match the regular expression below and capture its match into backreference number 1 «([\d\.]+)»
   Match a single character present in the list below «[\d\.]+»
      Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
      A single digit 0..9 «\d»
      A . character «\.»
Match the regular expression below and capture its match into backreference number 2 «(\s*[^\r\n]*?)»
   Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s*»
      Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
   Match a single character NOT present in the list below «[^\r\n]*?»
      Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
      A carriage return character «\r»
      A line feed character «\n»
Match the regular expression below and capture its match into backreference number 3 «([\d\.\-]+)»
   Match a single character present in the list below «[\d\.\-]+»
      Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
      A single digit 0..9 «\d»
      A . character «\.»
      A - character «\-»
Match the regular expression below and capture its match into backreference number 4 «(\s*[^\r\n]*\s[^\r\n]*\s*[^\r\n]*)»
   Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s*»
      Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
   Match a single character NOT present in the list below «[^\r\n]*»
      Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
      A carriage return character «\r»
      A line feed character «\n»
   Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s»
   Match a single character NOT present in the list below «[^\r\n]*»
      Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
      A carriage return character «\r»
      A line feed character «\n»
   Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s*»
      Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
   Match a single character NOT present in the list below «[^\r\n]*»
      Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
      A carriage return character «\r»
      A line feed character «\n»
Match the regular expression below and capture its match into backreference number 5 «(SPA0 SPB90 SPC-90|SPA0 SPB90 SPC-180)»
   Match either the regular expression below (attempting the next alternative only if this one fails) «SPA0 SPB90 SPC-90»
      Match the characters “SPA0 SPB90 SPC-90” literally «SPA0 SPB90 SPC-90»
   Or match regular expression number 2 below (the entire group fails if this one fails to match) «SPA0 SPB90 SPC-180»
      Match the characters “SPA0 SPB90 SPC-180” literally «SPA0 SPB90 SPC-180»

aeaede4f7a9f7a6f05bb5aa87b2d593a
Seppae
Seppae 04.09.2015 um 19:48:32 Uhr
Goto Top
Hallo Jodel32

Ich bin nochmal lästig. Sorry
Bei mir kommt die Fehlermeldung: Der Operator "<" wird noch nicht unterstützt
Müsste das < vor dem br in der ersten Zeile sein

Woran kann das liegen?

mfg Seppae
114757
114757 04.09.2015 aktualisiert um 19:55:50 Uhr
Goto Top
Woran kann das liegen?
Das ist ein aktueller Fehler des Forums beim kopieren aus dem Quelltext, siehe:
Entwicklertagebuch: Zitate, Text- und Codeblöcke

Du musst die HTML-Zeilenumbrüche <br /> am Ende jeder Zeile entfernen
pelzfrucht
pelzfrucht 04.09.2015 aktualisiert um 19:56:00 Uhr
Goto Top
Hallo,

die

<br />

Teile sollten normalerweise nicht im Code angezeigt werden.
Das ist ein aktueller Fehler in der Forensoftware.
Einfach mit Suchen & Ersetzen alle dieser HTML Code Schnipsel rausschmeißen.

Edit: Jodel war schneller face-smile
Seppae
Seppae 04.09.2015 um 20:46:38 Uhr
Goto Top
Danke!
Wenn ich ein bisschen Powershell verstehen würde hätte ich das wahrscheinlich sehen müssen.

@114757
irgendwie macht das programm leider gar nichts. Powershell öffnet sich und dann geschieht nix. reagiert auch auf keinen Tastendruck.
hab ich noch irgendwas vergessen? Oder muss ich noch was beachten/ändern am Programmcode (ausser dem Dateipfad)?

Muss mich jetzt mal intensiv mit Powershell beschäftigen...
Kennt ihr gute Seiten zum Thema?

Danke jedenfalls für euer Geduld
Super Forum!!! Daumen hoch

mfg Seppae
114757
114757 04.09.2015 aktualisiert um 20:56:11 Uhr
Goto Top
Zitat von @Seppae:
@114757
irgendwie macht das programm leider gar nichts. Powershell öffnet sich und dann geschieht nix. reagiert auch auf keinen Tastendruck.
hab ich noch irgendwas vergessen? Oder muss ich noch was beachten/ändern am Programmcode (ausser dem Dateipfad)?
Stichwort Executionpolicy
Hatte ich oben schon gepostet: https://www.windowspro.de/andreas-kroschel/powershell-scripts-ausfuehren
Muss mich jetzt mal intensiv mit Powershell beschäftigen...
Kennt ihr gute Seiten zum Thema?
Seppae
Seppae 04.09.2015 um 22:33:13 Uhr
Goto Top
Hallo Jodel
Habe mich geirrt, es funktioniert, war nur zu voreilig - dauert ein paar minuten bis die Datei durch ist. (über 2000 Zeilen lang)
Hab jetzt nur noch ein Problem:
Es ist nicht immer wie oben in meinem Beispiel, dass der y wert im negativen Bereich liegt. Aslo x und y können positiv oder negativ sein.
Dadurch stimmt dann die Rechnung nicht mehr.
Was muss ich machen um das Vorzeichen beim zu ändernden Wert miteinzubeziehen?

mfg Seppae
114757
114757 05.09.2015 aktualisiert um 01:54:31 Uhr
Goto Top
Zitat von @Seppae:

Hallo Jodel
Habe mich geirrt, es funktioniert, war nur zu voreilig - dauert ein paar minuten bis die Datei durch ist. (über 2000 Zeilen lang)
Hab jetzt nur noch ein Problem:
Es ist nicht immer wie oben in meinem Beispiel, dass der y wert im negativen Bereich liegt. Aslo x und y können positiv oder negativ sein.
Dadurch stimmt dann die Rechnung nicht mehr.
Was muss ich machen um das Vorzeichen beim zu ändernden Wert miteinzubeziehen?
Das tut das Script schon von Anfang an.

Ansonsten musst du genauer Spezifizieren was du mit dazuzählen und wegzählen bei negativen und positiven Zahlen meinst. Benutze hier doch bitte die allgemein bekannten Terme wie addieren und subtrahieren. Danke.

D.h. du willst immer nur den absoluten Wert betrachten also
Bei wenn X Positiv ist
35 - 0.05 = 34.95 ist klar
wenn negativ
-35 - 0.05 = also du willst -34.95 anstatt dem normalerweise rechnerisch richtigen Ergebnis von -35.05 ?

Willst du das so haben ?

Weil wenn mir jemand sagt ich soll von einer negativen Zahl etwas abziehen gehe ich ja davon aus das die Zahl noch kleiner wird.
Seppae
Seppae 05.09.2015 um 15:08:11 Uhr
Goto Top
Hallo,
Sorry für meine Ausdrucksweise, ich meinte natürlich schon das rechnerisch richtige, nicht absolut.
Hab auch den Fehler gefunden, in deinem originalen Code war einmal ein minus statt einem Plus
Auf jeden Fall funktioniert es jetzt.

Nun ein weiteres "Problem":
Ich habe deinen Code 4x kopiert (für 4 verschiedene Suchbegriffe - spa0 spb90 spc0, spa0 spb90 spc90, spa0 spb90 spc-90 und spa0 spb90 spc180)
Jetzt dauert das ganze über 10 min.
Kann man da noch was optimieren?
Ist es besser wenn ich es auf 4 scripts aufteile und diese nacheinander aufrufe?

mfg Seppae
114757
114757 05.09.2015 aktualisiert um 17:36:46 Uhr
Goto Top
Zitat von @Seppae:
Ich habe deinen Code 4x kopiert (für 4 verschiedene Suchbegriffe - spa0 spb90 spc0, spa0 spb90 spc90, spa0 spb90 spc-90 und spa0 spb90 spc180)
Ja nee, nicht 4 mal kopieren, wofür haben wir denn Regex face-smile du siehst in meinem Regex-Code das ich die Suchbegriffe am Ende jeweils mit einer Pipe | voneinander getrennt habe. Das bedeutet oder also trägst du deine Begriffe in das Regex so ein:
'(?sim)([\d\.\-]+)(\s*[^\r\n]*?)([\d\.\-]+)(\s*[^\r\n]*\s[^\r\n]*\s*[^\r\n]*)(spa0 spb90 spc0|spa0 spb90 spc90|spa0 spb90 spc-90|spa0 spb90 spc180)'
Seppae
Seppae 05.09.2015 aktualisiert um 17:54:51 Uhr
Goto Top
Naja
so einfach ist es leider nicht.
je nach such-string muss ich einmal x +0.05, y-0.05; einmal nur y-0.026 usw.
deshalb das ganze 4mal
oder hab ich wieder was falsch verstanden
114757
Lösung 114757 05.09.2015, aktualisiert am 06.09.2015 um 19:49:35 Uhr
Goto Top
so einfach ist es leider nicht.
Doch, das kannst du dann mit einer IF-Abfrage machen ...oder du baust eine Schleife um das Ganze und gibst die Werte als Variablen mit...feddich.
$file = 'C:\datei.txt'  
$start = get-date
$search = @{
'spa0 spb90 spc0'='0.05|0.03'  
'spa0 spb90 spc90'='0.06|0.02'  
'spa0 spb90 spc-90'='0.08|0.01'  
'spa0 spb90 spc180'= '0.02|0.10'  
}
$text = gc $file | out-string
$search.GetEnumerator() | %{
    $script:wert = $_.Value
    $text = [regex]::Replace($text,'(?sim)(X)([\d\.\-]+)(\s*[^\r\n]*?)(Y)([\d\.\-]+)(\s*[^\r\n]*?\s*[^\r\n]*?' + [regex]::Escape($_.Name) + ')' ,{  
        param($m)
        $xy = $script:wert.split('|')  
        $g1 = $m.Groups[1].Value
        $g2 = ([double]$m.Groups[2].Value) - ([double]$xy)
        $g3= $m.Groups[3].Value
        $g4= $m.Groups[4].Value
        $g5 = ([double]$m.Groups[5].Value) + ([double]$xy[1])
        $g6 = $m.Groups[6].Value
        return "$g1$g2$g3$g4$g5$g6"  
    })
}
$text | set-content $file
write-host "Finished in $(((get-date) - $start).TotalSeconds) Seconds"  
Seppae
Seppae 05.09.2015 um 18:15:55 Uhr
Goto Top
Ok, das würde das ganze ein wenig beschleunigen.
könntest du mir bei dem Ansatz nochmal etwas behilflich sein?
for schleife bzw if anweisung in regex einbinden...

mfg seppae
Seppae
Seppae 05.09.2015 aktualisiert um 18:39:20 Uhr
Goto Top
Hallo jodel32
Bekomme jetzt immer die meldung:
Sie können keine Methode für einen Ausdruck mit dem Wert Null aufrufen
$xy = $_.Value.split <<< ('|')

Hat er da ein Problem wenn ich nichts (habe dafür z.B. 0|0.03 eingetragen) addieren/subtrahieren will?

[edit] funktioniert auch nicht wenn ich 0.01 statt 0 eintrage.
zusätzlich kommt die fehlermeldung:
in einem Null-Array kann kein Index erstellt werden
114757
Lösung 114757 05.09.2015, aktualisiert am 06.09.2015 um 19:49:40 Uhr
Goto Top
nochmal kopieren, hatte noch was geändert..
Seppae
Seppae 06.09.2015 um 11:38:40 Uhr
Goto Top
Danke!
funktioniert, jedoch in etwa der gleichen Zeit, wie vorher (ca 10 min für die Datei mit ~66kb oder 2800 Zeilen).
Fällt da jemanden noch ein Trick ein, um das ganze zu beschleunigen?

mfg Seppae
114757
Lösung 114757 06.09.2015 aktualisiert um 19:49:44 Uhr
Goto Top
Hab's noch optimiert (da war der Regex suboptimal), sollte jetzt keine Sekunde mehr dauern .... Hab das gestern aus dem Kopf gezaubert da ich keinen Zugang zum Rechner hatte...
Meine Testdatei hatte dabei 10000 Zeilen Text. Das ganze hat dann 0.655 Sekunden gedauert.

Gruß jodel32

Wenns das dann war, den Beitrag bitte noch auf gelöst setzen.
Seppae
Seppae 06.09.2015 um 19:48:51 Uhr
Goto Top
Hallo jodel32,
1000 Dank jetzt funktioniert es einwandfrei.
Danke!!

Super Forum !!!
Seppae
Seppae 06.10.2015 um 12:51:37 Uhr
Goto Top
Hallo,
Ich müsste nochmal etwas optimieren im Programm:
Wie kann ich nach dem x und y Wert nun auch den Z wert miteinbinden, also ändern?
also zum Beispiel x+0.05, y-0.026, und z+0.2
Wäre toll wenn mir da nochmal jemand helfen könnte.

mit freundlichen Grüßen