misster
Goto Top

Eine .csv nach einem Wert dursuchen, der Zeilenbasiert immer an derselben Stelle steht und diesen dann ändern

Hallo,

bin ganz frisch hier und habe einige Threads hier schon durchsucht ohne meine Batch selbst hinzubekommen. Daher würde ich mich über eure Hilfe freuen! face-smile
Wie der Titel verrät habe ich eine .csv Datei. In dieser befindet sich eine Tabelle mit Überschriften und dann Zeilen und Spalten, es wird ";" als Trennzeichen verwendet - die Datei sieht also ungefähr so aus:
"ÜBERSCHRIFT1";"";"ÜBERSCHRIFT2";"ÜBERSCHRIF3";"ÜBERSCHRIFT4";"ÜBERSCHRIFT5";"ÜBERSCHRIFT6";"ÜBERSCHRIFT7";"ÜBERSCHRIFT8";"ÜBERSCHRIFT9";"ÜBERSCHRIFT10";"ÜBERSCHRIFT11"  
"12341234";"19.05.17 00:00:00";"!AB12CDE12345687641414!";"BLA";"0200001";"SHDSHD22XXX";"Lorem Ipsum";"Actual";"Look";"Werte";"Wasauchimmer";"AB12CDE12345687641414"  
"33444";"19.05.17 00:00:00";"AB12CDE12345687641414";"Bla BLA";"0200001";"SHDSHD22XXX";"Lorem Ipsum";"Actual";"Look";"Werte";"Wasauchimmer";"AB12CDE12345687641414"  

Mein Ziel ist den mit Ausrufezeichen markierten Wert zu finden und in eine String variable zu packen, die Zeile anschließend danach zu durchsuchen und den Werte durch einen zufälligen, möglichst sinnvollen(selbe alphanumerische Aufteilung) Wert zu ersetzen. Dies soll für die ganze Datei, Zeile für Zeile passieren.
Da ich bisher nur rudimentäre Batch gebastelt habe (Dienste starten/stoppen, Dateien automatischen verschieben/löschen, usw.) fehlt mir da so einiges an Wissen (C++ aus der Berufsschule hilft da fast gar nicht).

Bisher habe ich es geschafft einen Ordner zu erstellen und eine Kopie der Datei darin zu erstellen. Dann Wird gebprüft ob die Datei auch die Richtige ist und es beginnt eine FOR Schleife an der ich Scheitere:
@echo off & setlocal

REM Declare variables
set counter=0
set strvar=test
set path="C:\tmpcache\Dateiname.csv"  
	
REM Create a cache an copy the folder
	mkdir C:\tmpcache
	copy /-y C:\Tmp_Analytics C:\tmpcache

REM Check the file to assure the content is correct
	find  "VALUE" "C:\tmpcache\Dateiname.csv"  
	IF errorlevel 1 (
		echo Falsche Datei. 
	) ELSE (
		echo Richtige Datei. 
	)

(for %%f in ("C:\tmpcache\*.csv") do (   
   type "%%~f" | find ";"  > NUL && (  
     echo %%~f
   )
  ))

REM delete the cached file
	del %path%
pause 	

Der Ansatz der Vorschleife ist ein Produkt aus dem Artikel. Leider bin ich nicht ganz durchgestiegen.

Generell war mein Gedanke eine verschachtelte FOR-Schleife zu bauen, bei der die erste Schleife einmal die ganze Datei durchgeht und die Zweite dann Zeile für Zeile an der richtigen Stelle (der Text zwischen dem Zweiten und dem Dritten Semikolon) prüft. Dann sollen alle gefundenen Werte ersetzt werden.

Vielen Dank schonmal im Voraus,
mIsSteR

Content-Key: 344401

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

Printed on: April 26, 2024 at 12:04 o'clock

Mitglied: 133883
133883 Jul 25, 2017 updated at 11:31:11 (UTC)
Goto Top
@echo off
powershell -ExecutionPolicy ByPass -Command "(gc 'C:\tmpcache\Dateiname.csv') -replace '!AB12CDE12345687641414!','WhateverReplacement' | sc 'C:\tmpcache\Dateiname.csv'"  
Member: mIsSteR
mIsSteR Jul 25, 2017 at 11:40:43 (UTC)
Goto Top
Hi exguru,
vielen Dank für deine Antwort face-smile

Wenn ich deinen Ansatz richtig verstehe, muss ich davor noch irgendwie herausfinden wie der String an dieser Stelle heißt, ab dann werden alle Werte ersetzt. Das hilft mir schon weiter face-smile

Wenn ich das falsch verstanden hab, nicht zimperlich sein und druff hauen, dann lern ich's am Besten.

VG,
mIsSteR
Mitglied: 133883
133883 Jul 25, 2017 updated at 11:44:34 (UTC)
Goto Top
Zitat von @mIsSteR:
Wenn ich deinen Ansatz richtig verstehe, muss ich davor noch irgendwie herausfinden wie der String an dieser Stelle heißt
Du schreibst ja oben leider nirgendwo das du ihn nicht kennst. Aber wenn du ihn nicht kennst, auch kein Problem, bisschen Regex eingestreut geht natürlich auch das
powershell -ExecutionPolicy ByPass -Command "(gc 'C:\tmpcache\Dateiname.csv') -replace '![^!]+!','WhateverReplacement' | sc 'C:\tmpcache\Dateiname.csv'"  
Member: mIsSteR
mIsSteR Jul 25, 2017 at 12:00:05 (UTC)
Goto Top
Zitat von @133883:

Du schreibst ja oben leider nirgendwo das du ihn nicht kennst. Aber wenn du ihn nicht kennst, auch kein Problem, bisschen Regex eingestreut geht natürlich auch das

Das ist mein Fehler sorry! Leider kenne ich den Inhalt der .csv nie. Lediglich weiß ich sicher, dass der benötigte String zwischen dem zweiten und dritten Semikolon steht.
Regex habe ich gerade zum ersten mal gelesen/gehört. Aus dem gelesenen werde ich bisher nicht so schlau, muss ich mir mal etwas näher anschauen!
Dann versuche ich deinen Code mal einzubauen.

Vielen Dank!
Member: mIsSteR
mIsSteR Jul 25, 2017 at 13:16:02 (UTC)
Goto Top
Hi exguru,
habe den Code angepasst und er wirft keine Fehler, allerdings ersetzt er nichts. In den Befehlen in deinem Code wird eine PowerShell gestartet, die zuerst die Execution Policy umgeht und dann das Command bekommt in 'C:\tmpcache\Dateiname.csv' ein replace auszuführen - und zwar den Wert '![!]+!' durch 'WhateverReplacement' in der Datei 'C:\tmpcache\Dateiname.csv'. Korrekt?
Wenn ja, vermute ich, dass die RegEx noch nicht passt. In dem Thema RegEx bin ich leider noch nicht durchgestiegen, kannst du mir dabei helfen einen entsprechenden Ausdruck zu erstellen?

Viele Grüße,
mIsSteR
Mitglied: 133883
133883 Jul 25, 2017 updated at 13:46:27 (UTC)
Goto Top
replace auszuführen - und zwar den Wert '![!]+!' durch 'WhateverReplacement' in der Datei
Ja nee, schau dir den Pattern noch mal genau an !!! Du hast das essentielle ^ einfach weg gelassen ohne zu wissen was du damit anrichtest face-smile.
Funktioniert einwandfrei.
Member: mIsSteR
mIsSteR Jul 25, 2017 at 13:51:02 (UTC)
Goto Top
Oh ja stimmt, im Batch ist es jedoch drin.
Heute ist wohl mein zweiter Montag diese Woche...
Mitglied: 133883
133883 Jul 25, 2017 updated at 17:32:13 (UTC)
Goto Top
Quell-Datei sieht so aus:
"ÜBERSCHRIFT1";"";"ÜBERSCHRIFT2";"ÜBERSCHRIF3";"ÜBERSCHRIFT4";"ÜBERSCHRIFT5";"ÜBERSCHRIFT6";"ÜBERSCHRIFT7";"ÜBERSCHRIFT8";"ÜBERSCHRIFT9";"ÜBERSCHRIFT10";"ÜBERSCHRIFT11"  
"12341234";"19.05.17 00:00:00";"!AB12CDE12345687641414!";"BLA";"0200001";"SHDSHD22XXX";"Lorem Ipsum";"Actual";"Look";"Werte";"Wasauchimmer";"AB12CDE12345687641414"  
"33444";"19.05.17 00:00:00";"AB12CDE12345687641414";"Bla BLA";"0200001";"SHDSHD22XXX";"Lorem Ipsum";"Actual";"Look";"Werte";"Wasauchimmer";"AB12CDE12345687641414"  
Nach Anwenden von
@echo off
powershell -ExecutionPolicy ByPass -Command "(gc 'C:\test.txt') -replace '![^!]+!','WhateverReplacement' | sc 'C:\test.txt'"  
sieht sie die gleiche Datei so aus
"ÜBERSCHRIFT1";"";"ÜBERSCHRIFT2";"ÜBERSCHRIF3";"ÜBERSCHRIFT4";"ÜBERSCHRIFT5";"ÜBERSCHRIFT6";"ÜBERSCHRIFT7";"ÜBERSCHRIFT8";"ÜBERSCHRIFT9";"ÜBERSCHRIFT10";"ÜBERSCHRIFT11"  
"12341234";"19.05.17 00:00:00";"WhateverReplacement";"BLA";"0200001";"SHDSHD22XXX";"Lorem Ipsum";"Actual";"Look";"Werte";"Wasauchimmer";"AB12CDE12345687641414"  
"33444";"19.05.17 00:00:00";"AB12CDE12345687641414";"Bla BLA";"0200001";"SHDSHD22XXX";"Lorem Ipsum";"Actual";"Look";"Werte";"Wasauchimmer";"AB12CDE12345687641414"  
Also der String !AB12CDE12345687641414! der mit führendem und abschließendem Ausrufezeichen gesucht wurde ersetzt durch WhateverReplacement. Also alles i.O.
Der Regex besagt: Suche einen String mit einem Ausrufezeichen am Anfang und am Ende und dazwischen egal welches Zeichne außer einem Ausrufezeichen mindestens 1mal.

k.A. was du sonst willst, oder du beschreibst es falsch...
Member: mIsSteR
mIsSteR Jul 26, 2017 updated at 06:40:17 (UTC)
Goto Top
Guten Morgen exguru,

da habe ich mich wohl missverständlich ausgedrückt. Jetzt wurde mir klar wo das Missverständnis ist: Der unbekannte String ist immer der zwischen dem zweiten und dritten Semikolon jeder Zeile, die Ausrufezeichen sind zur Markierung in dem als Code markierten Beispiel und kommen sonst gar nicht in der CSV vor.

EDIT: Ich hatte ursprünglich vor das CSV-Beispiel nicht als Code formatieren sondern als Text und den benötigten Strin fett zu markieren, das wäre im nachinein besser gewesen.
Mitglied: 133883
133883 Jul 26, 2017 updated at 06:43:30 (UTC)
Goto Top
OK, aber nach welchem Muster willst du denn jetzt in der dritten Spalte suchen??? Egal was Hauptsache mind. ein Buchstabe/Ziffer oder was?
Member: mIsSteR
mIsSteR Jul 26, 2017 updated at 08:09:22 (UTC)
Goto Top
In der dritten Spalte stehen IBANs aus verschiedenen Ländern da ist weder die Anzahl der Zeichen, noch wann genau Zahlen oder Zeichen kommen, definiert. Es sind aber immer mindestens 20 Zeichen.
Und dieser IBAN soll dann Zeile für Zeile ausgetauscht werden (am besten mit etwas das wie ein IBAN aussieht face-smile )

EDIT: ich könnte mir einen Ausdruck wie folgend vorstellen: '[A-Z]{2}[0-9]{2,32}' denn IBANS haben immer vorne zwei Buchstaben zur Länderkennung und dann folgen mindestens zwei Zahlen
Mitglied: 133883
Solution 133883 Jul 26, 2017 updated at 09:09:05 (UTC)
Goto Top
Pfad in Zeile 1 und Spaltenname der IBAN in Zeile 2 anpassen.

Wurde getestet, funktioniert. Achtung überschreibt Quell-Datei, wenn nicht gewünscht bei export-csv den Pfad entsprechend abändern.
$file = 'C:\Daten\datei.csv'  
$colname = "ÜberschriftDerSpalte3"  

$alpha = (65..90 | %{[char]$_})
$csv = Import-CSV $file -Delimiter ";"  
$csv | %{
    $num = $_.$colname; $row = $_
    $random = [regex]::replace($num,'.',{param($m) if ($m.Value -match '[A-Z]'){$alpha | Get-Random}else{0..9 | get-random}})  
    $_ | gm -MemberType NoteProperty | ?{$row.($_.Name) -like "*$num*"} | %{$row.($_.Name) = $row.($_.Name) -replace $num,$random}  
    $row
} | export-csv $file -Delimiter ";" -NoType -Encoding UTF8  

Wie man mit PS1 Dateien umgeht brauche ich hier hoffentlich nicht nochmal abhandeln.

Viel Erfolg
Ciao.
Member: mIsSteR
mIsSteR Jul 26, 2017 at 09:32:50 (UTC)
Goto Top
Klappt, vielen Dank!