Batch String suchen und Wert addieren

R3van

Ensign
🎅 Nikolaus-Rätsel-Elite
Registriert
Feb. 2007
Beiträge
144
Hallo,

ich habe hier ein Textfile mit über 500 Einträgen bei denen ich Werte ändern muss.

Das sieht so aus:
Code:
  TOOL:0
  MIN:{3.0524}
  MAX:{3.0524}
  UNIT:{MM}

Hier muss ich also von Min 0.0001 subtrahieren und zu Max 0.0001 hinzuaddieren.

Möchte das ungerne per Hand erledigen und dachte an ein Batchfile. Ist so was möglich und wenn ja, wie?
 
Muss es Batch sein? Batch ist für sowas einfach nur ein Krampf. Es wäre sogar einfacher, das Textfile in Excel einzulesen, den Wert mittels TEIL-Funktion zu extrahieren und zu berechnen. Das Ergebnis kann man dann wieder in eine Text- bzw. CSV-Datei exportieren.

Alternativ würde ich das sonst eher mit wsh (Windows Scripting Host) oder PowerShell machen.
 
  • Gefällt mir
Reaktionen: rocketworm und DeusoftheWired
Nein, muss keine Batch sein, Powershell ginge auch. Excel wird eher schwierig.
 
R3van schrieb:
Excel wird eher schwierig.

Open Office oder Libre Office Calc geht genauso wenn du kein Excel hast. Ich gebe da Raijin recht dass man da mit Excel oder einem ähnlichen Programm schneller und einfacher zum Ziel kommt als nen Skript zu bauen.

Wenn man es regelmäßig braucht, mag es noch was anderes sein....
 
Ich hab schon Excel, befürchte aber das das schwieriger zum umsetzen bzw. importieren ist als die Script Variante.
Das Textfile muss hinterher halt auch wieder genau so aussehen bzw. formatiert sein wie vorher

Lass mich aber gerne eines besseren
 
probier das mal
PowerShell:
$datein = Get-ChildItem -Recurse "<Pfad>" -Include "*.txt"
ForEach ($datei in $datein){       
        $array = Get-Content $datei
        $min = $array[1]
        $array[1] = "MIN:{" + ((([decimal]$min.substring(5,6)) - 0.0001)-replace',','.') + "}"
        $max = $array[2]
        $array[2] = "MAX:{" + ((([decimal]$max.substring(5,6)) + 0.0001)-replace',','.') + "}"
        Out-File -Encoding default -filepath $datei.fullname -InputObject $array
        
    }
Kann man bestimmt eleganter lösen aber bei meinen Tests hats funktioniert. Backup vorher nicht vergessen.
 
  • Gefällt mir
Reaktionen: Raijin
Super, vielen Dank :schluck:

Gibt leider noch eine Fehlermeldung:
Code:
Ausnahme beim Aufrufen von "Substring" mit 2 Argument(en):  "Der Index und die Länge müssen sich auf eine Position in der Zeichenfolge
beziehen.
Parametername: length"
In Zeile:5 Zeichen:9
+         $array[1] = "MIN:{" + ((([decimal]$min.substring(5,6)) - 0.00 ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

Der Wert "E:{DIA" kann nicht in den Typ "System.Decimal" konvertiert werden. Fehler: "Die Eingabezeichenfolge hat das falsche Format."
In Zeile:7 Zeichen:9
+         $array[2] = "MAX:{" + ((([decimal]$max.substring(5,6)) + 0.00 ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastFromStringToDecimal

Mir ist nicht klar, warum "E:{DIA" zum bearbeiten ausgewählt wird.
So wie ich das verstehe sollten die Funktionen nur bei den Strings mit MIN:{...} und MAX:{...} greifen oder?

Weiter vorne im File steht noch dieses:
Code:
DATA:{
  NAME:{DIA}
  TYPE:{MM}
}
Warum wird da auch versucht, den String zu ändern wenn dieser gar nicht mit MIN oder MAX beginnt?
 
Ich bin jetzt von deinem Bsp. oben ausgegangen. Dachte das ist allen Dateien gemein, falls sich was ändert funktioniert das dann nicht mehr.

Mir ist nicht klar, warum "E:{DIA" zum bearbeiten ausgewählt wird.
So wie ich das verstehe sollten die Funktionen nur bei den Strings mit MIN:{...} und MAX:{...} greifen oder?
Weil die ganze Datei eingelesen wird und dann die 2. und 3. Zeile bearbeitet werden. Danach wird die Datei geleert und wieder befüllt. Sollten mehr Zeilen in der Datei sein funktioniert es evtl. nicht mehr.
 
Ich ging jetzt auch davon aus, dass die Datei wie im ersten Beitrag aussieht, eben nur mit mehreren dieser Blöcke hintereinander. Wenn dem nicht so ist, dann bitte ein vollständiges Beispiel posten, nicht zwingend mit 500 Zeilen, aber so dass die gegebene Struktur erkennbar wird.
 
ok, sorry...
Code:
VERSION:3
DATA:{
  NAME:{DIA}
  TYPE:{MM}
}
DATA:{
  NAME:{PREDRILL}
  TYPE:{MM}
}
DATA:{
  NAME:{DURCH}
  TYPE:{STRING}
}
DATA:{
  NAME:{NIBDRA}
  TYPE:{BOOLEAN}
}
DATA:{
  NAME:{NIBFLA}
  TYPE:{BOOLEAN}
}
DATA:{
  NAME:{NK}
  TYPE:{BOOLEAN}
}
DATA:{
  NAME:{FRAESER}
  TYPE:{BOOLEAN}
}
ENTRY:{
  1
  TOOL:0
  MIN:{3.0240}
  MAX:{3.0240}
  UNIT:{MM}
  DATA:{ NAME:{DURCH} VALUE:{305} }
  DATA:{ NAME:{NIBDRA} VALUE:{0} }
  DATA:{ NAME:{FRAESER} VALUE:{0} }
  DATA:{ NAME:{PREDRILL} VALUE:{0.0000} }
  DATA:{ NAME:{NIBFLA} VALUE:{0} }
  DATA:{ NAME:{DIA} VALUE:{3.0240} }
  DATA:{ NAME:{NK} VALUE:{0} }
}
ENTRY:{
  2
  TOOL:0
  MIN:{3.0540}
  MAX:{3.0540}
  UNIT:{MM}
  DATA:{ NAME:{DURCH} VALUE:{305} }
  DATA:{ NAME:{NIBDRA} VALUE:{0} }
  DATA:{ NAME:{FRAESER} VALUE:{0} }
  DATA:{ NAME:{PREDRILL} VALUE:{0.0000} }
  DATA:{ NAME:{NIBFLA} VALUE:{0} }
  DATA:{ NAME:{DIA} VALUE:{3.0540} }
  DATA:{ NAME:{NK} VALUE:{0} }
}
...
...
...
ENTRY:{
  534
  TOOL:0
  MIN:{3.0100}
  MAX:{3.0100}
  UNIT:{MM}
  DATA:{ NAME:{DURCH} VALUE:{300} }
  DATA:{ NAME:{NIBDRA} VALUE:{0} }
  DATA:{ NAME:{FRAESER} VALUE:{1} }
  DATA:{ NAME:{PREDRILL} VALUE:{0.0000} }
  DATA:{ NAME:{NIBFLA} VALUE:{0} }
  DATA:{ NAME:{DIA} VALUE:{3.0100} }
  DATA:{ NAME:{NK} VALUE:{0} }
}
 
Ist nur eine Datei. Morgen reicht auch noch...
 
Na dann würd ichs fast echt mit Excel machen, das ist dann glaub ich schneller. Ich dachte es geht um mehrere Dateien.
Ergänzung ()

Aber Nun
PowerShell:
$Datei = "<Datei+pfad>"
$Zeilen =  Get-Content -Path $Datei
$ZeilenZähler = 1
foreach($Zeile in $Zeilen)
    {
        IF ($Zeile -cmatch "  MAX:{.*}") {
        $Zeile = "  MAX:{" + ((([decimal]$Zeile.substring(7,6)) + 0.0001)-replace',','.') + "}"
        }
        
        IF ($Zeile -cmatch "  MIN:{.*}") {
        $Zeile = "  MIN:{" + ((([decimal]$Zeile.substring(7,6)) - 0.0001)-replace',','.') + "}"
        }
        
        If($ZeilenZähler -eq 1 ) {
           Out-File -Encoding UTF8 -FilePath $Datei -InputObject $Zeile -Force
        }
        Else {
            Out-File -Encoding UTF8 -FilePath $Datei -InputObject $Zeile -Force -Append
        }
        
        
        $ZeilenZähler++
    }
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Raijin
👍 Top, danke. Ich probiers morgen gleich aus.
 
Ausgehend davon, dass die Datei 500 Zeilen hat und nur aus solchen Entry-Blöcken besteht, die ihrerseits 13 Zeilen lang sind, wärst du damit schon längst durch, wenn du das manuell gemacht hättest. Ein Script, sei es eine Batch, PowerShell oder auch via Excel, ist nur dann sinnvoll, wenn es einerseits um eine enorme Menge an Daten geht oder man die Aktion regelmäßig wiederholen muss. Da ersteres nicht der Fall ist (wir reden von ~35 Vorkomnissen, da ist man in 5 Minuten per Hand durch) hoffe ich mal dass wenigstens letzteres der Fall ist ;)

Das was du jetzt an Zeit gespart hast, ist die Zeit, die @sikarr und ich (er war mit dem Skript einfach schneller) investiert haben.
 
Nun, ich habe jedenfalls keinen kompletten Code erwartet sondern eher so was in der Richtung "Probier mal dies oder jenes..."
Das ich das jetzt trotzdem von sikarr bekommen habe finde ich sehr nett und weiß ich auch durchaus zu schätzen.
534 Einträge mal zwei macht 1068 Änderungen. Grund genug für mich, zumindest mal zu versuchen das zu automatisieren bevor ich das per Hand mache. Und da ich ja jetzt auch selber rumprobiert habe hab ich auch nicht wirklich Zeit eingespart (Was auch nicht mein vorrangiges Ziel war).
 
Aso, ich hatte das so verstanden, dass die ganze Datei 500 Zeilen hat. Dann nehme ich alles zurück und behaupte glatt das Gegenteil ;)
 
Habs auch für mich gemacht um in PS besser zu werden. Um Fair zu bleiben, das 2. Script hab ich auch irgendwo mal gemobbst, und immer weiter angepasst, ist also nicht komplett auf meinem Mist gewachsen. Hab nur die beiden IF klauseln eingefügt, und eine Foreach-Schleife entfernt da es mal für mehrere Dateien gedacht war ;).
 
Hat super funktioniert :daumen:

Hab noch die Pfadangabe angepasst:
Code:
$Datei = "$PSScriptRoot\DRILL.ttb"
$Zeilen =  Get-Content -Path $Datei
$ZeilenZähler = 1
foreach($Zeile in $Zeilen)
    {
        IF ($Zeile -cmatch "  MAX:{.*}") {
        $Zeile = "  MAX:{" + ((([decimal]$Zeile.substring(7,6)) + 0.0001)-replace',','.') + "}"
        }
        
        IF ($Zeile -cmatch "  MIN:{.*}") {
        $Zeile = "  MIN:{" + ((([decimal]$Zeile.substring(7,6)) - 0.0001)-replace',','.') + "}"
        }
        
        If($ZeilenZähler -eq 1 ) {
           Out-File -Encoding UTF8 -FilePath $Datei -InputObject $Zeile -Force
        }
        Else {
            Out-File -Encoding UTF8 -FilePath $Datei -InputObject $Zeile -Force -Append
        }
        
        
        $ZeilenZähler++
    }

Vielen Dank noch mal 👍
 
  • Gefällt mir
Reaktionen: Raijin
Zurück
Oben