PS-Skript in Batch umwandeln
Hallo zusammen,
ich stehe wieder vor einem Problem, welches mir enorme Zeit raubt. Durch ein externes Softwareprogramm, muss ein Dateiinhalt umgewandelt werden. Das Programm kann nur Batch-Skripte ausführen. Ich muss deswegen also ein bisschen Tricksen um den Dateiinhalt zu verändern, via Powershell. Leider gibt es hier einige Probleme weswegen ich mich gezwungen fühle alles in einer Batch umzusetzen.
Hierbei gibt es folgenden Datei aufbau:
Quelldatei (eig CSV, wird aber normal als Txt behandelt)
Diese Konvention is jedoch falsch und müsste in:
umgeändert werden. Sprich: das Erste " einer Zeile und letzte " einer Zeile muss entfernt werden, sowie das "" durch ein " ersetzt werden.
In PowerShell habe ich es so gelöst:
Und in der Batch übergeben:
Leider kommt es wie oben erwähnt dazu, dass das Programm ungern ein Powershellcommand umsetzen möchte.
Wie schreibe ich die Logik von PowerShell in ein Batch-Skript um? Schon das arbeiten mit Zeichenketten kann sehr unintuitiv bei Batch werden.
Ich bedanke mich vorab recht herzlichst!
ich stehe wieder vor einem Problem, welches mir enorme Zeit raubt. Durch ein externes Softwareprogramm, muss ein Dateiinhalt umgewandelt werden. Das Programm kann nur Batch-Skripte ausführen. Ich muss deswegen also ein bisschen Tricksen um den Dateiinhalt zu verändern, via Powershell. Leider gibt es hier einige Probleme weswegen ich mich gezwungen fühle alles in einer Batch umzusetzen.
Hierbei gibt es folgenden Datei aufbau:
Quelldatei (eig CSV, wird aber normal als Txt behandelt)
"A,B,C,D,E,""F1,F2,F3"",G,H,I"
...
...
Diese Konvention is jedoch falsch und müsste in:
A,B,C,D,E,"F1,F2,F3",G,H,I
...
...
umgeändert werden. Sprich: das Erste " einer Zeile und letzte " einer Zeile muss entfernt werden, sowie das "" durch ein " ersetzt werden.
In PowerShell habe ich es so gelöst:
param($Data1, $Data2)
$check=(Get-Content $Data1)
foreach($i in $check){
if($i.Substring(0,1) -eq '"')
{
(Get-Content $Data1)|
%{$_.replace("(?'name'"")",'"').remove(0,1)}|
%{$_.replace(',""',',"')}|
%{$_.replace('"",','",')}|
%{$_.remove($_.length-1,1)}|
Set-Content $Data2
}
}
Und in der Batch übergeben:
@echo off
Powershell.exe -Command "& {Start-Process Powershell.exe -ArgumentList '-ExecutionPolicy Bypass -File "CHECK.ps1 -Data1 "%1", -Data2 "%2""'}
Leider kommt es wie oben erwähnt dazu, dass das Programm ungern ein Powershellcommand umsetzen möchte.
Wie schreibe ich die Logik von PowerShell in ein Batch-Skript um? Schon das arbeiten mit Zeichenketten kann sehr unintuitiv bei Batch werden.
Ich bedanke mich vorab recht herzlichst!
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 568065
Url: https://administrator.de/contentid/568065
Ausgedruckt am: 22.11.2024 um 12:11 Uhr
16 Kommentare
Neuester Kommentar
@echo off
set "file=%~1"
powershell -EP ByPass -C "((gc '%file%') -replace '^\x22|\x22$','') -replace '\x22{2}','\"' | sc '%file%'"
mybatch.cmd "C:\mytextfile.txt"
(gc '%fileIN%')
-replace '^\x22|\x22$','')
-replace '\x22{2}','\"'
Des Weiteren liefert die Konsole zurück das "sc" unbekannt ist. Also interpretiert er die Zeile nicht sauber.
Das ist ein Alias für Set-Content. Wenn das deine Shell nicht kennt ist deine PS entweder zu alt, oder du hast den Alias entfernt, du kannst aber auch die anderen cmdlets wie out-file nehmen usw.Wichtig wäre dass die veränderte Datei in eine neue Ausgespuckt wird, deswegen habe ich mit %1 und %2 gearbeitet, da wir die originale nicht verändern wollen.
Kein Problem@echo off
set "fileIN=%~1"
set "fileOUT=%~2"
powershell -EP ByPass -C "((gc '%fileIN%') -replace '^\x22|\x22$','') -replace '\x22{2}','\"' | out-file '%fileOUT%'"
Plain Batch geht auch
@echo off &setlocal enabledelayedexpansion
:: Eingabedatei aus Parameter 1 Variablen zuweisen
set "fileIN=%~1"
:: Ausgabedatei aus Parameter 2 Variablen zuweisen
set "fileOUT=%~2"
:: Ausgabe der FOR-Schleife an Ausgabedatei senden (FOR-Schleife verarbeitet alle nicht leeren Zeilen)
:: erste Anweisung weist den Inhalt der Zeile der Variablen "line" zu
:: zweite Anweisung entfernt erstes und letztes Zeichen
:: dritte Anweisung ersetzt doppelte Anfürhungszeichen durch einfache
:: vierte Anweisung gibt die modifizierte Zeile aus
>"%fileOUT%" (for /f "usebackq delims=" %%a in ("%fileIN%") do (
set "line=%%a"
set "line=!line:~1,-1!"
set "line=!line:""="!"
echo.!line!
))
Zitat von @robdox:
Dürfte ich noch um die Auflösung vom Batch-Skript bitten? Möchte die Zeilen auch verstehen können. Danke jedoch für alles schonmal vorab!
Kommentare sind dort oben im Beitrag noch ergänzt, für die Erläuterung der Details einer FOR-Schleife einfach mal Dürfte ich noch um die Auflösung vom Batch-Skript bitten? Möchte die Zeilen auch verstehen können. Danke jedoch für alles schonmal vorab!
for /?
in deine Konsole eingeben.Danke jedoch für alles schonmal vorab!
Bitte, keine Ursache.
Für die Prüfung in der Condition kannst du auch andere Zeichen nehmen die die Variablen umschließen, du musst dort nicht zwingend Anführungszeichen nutzen ... Du hast hier aber in der Zeichenextraktion aber auch einen Fehler eingebaut...
Zm Escaping siehe
https://www.robvanderwoude.com/escapechars.php
>"%fileOUT%" (for /f "usebackq delims=" %%a in ("%fileIN%") do (
set "line=%%a"
echo.!line!|findstr /b """" >nul 2>&1 && (
set "line=!line:~1,-1!"
set "line=!line:""="!"
)
echo.!line!
))
Zm Escaping siehe
https://www.robvanderwoude.com/escapechars.php
Hi!
Eine Alternative zum Umwandeln von . ps1 zu .cmd oder .bat wäre, dem Batch einfach die Ausführung der PS-Scripte zu befehlen:
So würdest du dir viel Zeit ersparen wegen des Umwandeln des PS-Codes und den vielen Eventualitäten die da auftreten könnten.
Grüße!
Eine Alternative zum Umwandeln von . ps1 zu .cmd oder .bat wäre, dem Batch einfach die Ausführung der PS-Scripte zu befehlen:
Powershell.Exe -ExecutionPolicy Bypass -File "Pfad zum PS-Script"
So würdest du dir viel Zeit ersparen wegen des Umwandeln des PS-Codes und den vielen Eventualitäten die da auftreten könnten.
Grüße!
Ach nee das gibt Kuddel, mach den FOR-Teil besser so
>"%fileOUT%" (for /f "usebackq delims=" %%a in ("%fileIN%") do (
set "line=%%a"
echo.!line!|findstr /b """" >nul 2>&1 && (
set "line=!line:~1,-1!"
set "line=!line:""="!"
)
echo.!line!
))
Ja.
Ausgeben lassen kannst du dir alles mit echo und Abfragen kannst du machen mit set /p oder choice. Einfach mal das Manual lesen . So denn, tschö mit ö.
Und: Das kurze warten von 2 sek, wieso müssen wir dies tun in der Verarbeitung? Damit er erstmal alle Zeilen überprüft und dann verändert ggf.?
Du sprichst in Rätseln ??Ausgeben lassen kannst du dir alles mit echo und Abfragen kannst du machen mit set /p oder choice. Einfach mal das Manual lesen . So denn, tschö mit ö.