Powershell Datei einlesen, Datensätze mit anderer Datei vergleichen und ändern
Hallo zusammen,
ich bin komplett neu in Powershell. Nun ist meine Aufgabe aus einer Excel datei eine Spalte mit ID´s einzulesen, und sie mit ID´s in einer Text Datei zu vergleichen, sind sie identisch muss in der Textdatei der eintrag unter der jeweiligen ID geändert werden. Ich habe absolut keine vorstellung wie ich das realisieren soll. Freue mich über jede Hilfe!
ich bin komplett neu in Powershell. Nun ist meine Aufgabe aus einer Excel datei eine Spalte mit ID´s einzulesen, und sie mit ID´s in einer Text Datei zu vergleichen, sind sie identisch muss in der Textdatei der eintrag unter der jeweiligen ID geändert werden. Ich habe absolut keine vorstellung wie ich das realisieren soll. Freue mich über jede Hilfe!
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 214742
Url: https://administrator.de/contentid/214742
Ausgedruckt am: 13.11.2024 um 01:11 Uhr
9 Kommentare
Neuester Kommentar
Hallo,
ich arbeite mich auch gerade in PowerShell ein, eine Verbindung zum Excel habe ich schonmal.
Das funktioniert so:
Wenn du diesen Code übernimmst und deinen Pfad der Mappe anpasst, sollte er dir den Wert aus der 1. Spalte in der 1. Zeile ausgeben.
In dem Fall im Excel A1.
Weiter Arbeiten kannst du dann mit $feld_inhalt, wenn du alles richtig gemacht hast sollte dort nun die ID drin stehen.
Verknüpfung zu einer Text-Datei habe ich gerade nicht auf dem Schirm.
Viele Grüße.
ich arbeite mich auch gerade in PowerShell ein, eine Verbindung zum Excel habe ich schonmal.
Das funktioniert so:
$ExcelMappe = "C:\xxxx\NeueTestMappe.xlsx" #Deine XLSX Mappe.
#Excel Objekt wird erstellt
echo "Excel Objekt wird erstellt.."
$Excel = new-object -comobject Excel.application
$Excel.visible = $True
# Öffnet bestehende Excel Datei
echo "Bestehende Vorlage wird geoeffnet: $ExcelMappe"
$WorkBook = $Excel.WorkBooks.open($ExcelMappe)
$Sheet = $WorkBook.ActiveSheet
$cells=$Sheet.Cells
#Spalte und Zeile Definieren
$Spalte = 1
$Zeile = 1
# Zum Auslesen der Felder:
$feld_inhalt = $Cells.Item($Spalte,$Zeile).value2
#Zum Ausgeben (Ob alles geklappt hat)
$feld_inhalt
Wenn du diesen Code übernimmst und deinen Pfad der Mappe anpasst, sollte er dir den Wert aus der 1. Spalte in der 1. Zeile ausgeben.
In dem Fall im Excel A1.
Weiter Arbeiten kannst du dann mit $feld_inhalt, wenn du alles richtig gemacht hast sollte dort nun die ID drin stehen.
Verknüpfung zu einer Text-Datei habe ich gerade nicht auf dem Schirm.
Viele Grüße.
Ja genau, das kannst du in einer einfachen While-Schleife wiederholen.
Wegen der ID aus deiner TXT File schau dir diesen Link:
blog.stefanrehwald.de/2013/02/27/powershell-03-1-strings-auf-bestimmten-inhalt-prufen-mit-dem-parameter-match/
mal an, dort geht es um -match, der vergleicht auch Sachen, egal was davor/dahinter steht.
Viele Grüße.
Wegen der ID aus deiner TXT File schau dir diesen Link:
blog.stefanrehwald.de/2013/02/27/powershell-03-1-strings-auf-bestimmten-inhalt-prufen-mit-dem-parameter-match/
mal an, dort geht es um -match, der vergleicht auch Sachen, egal was davor/dahinter steht.
Viele Grüße.
Hallo christianrutz,
alles kein Problem. Ohne weitere Informationen zu deiner Textdatei, gehe ich jetzt mal z.B. von folgendem Format deiner Textdatei aus:
Dann kannst du mit folgendem Code arbeiten:
(Kommentare sind im Code abgelegt)
Die grundlegende Arbeitsweise zum finden der IDs ist folgende: Das Script arbeitet mit zwei verschachtelten FOR-Schleifen die äußere Schleife arbeitet die IDs in Excel nacheinander ab und die zweite durchläuft die Zeilen der Textdatei nacheinander und durchsucht dabei jede Zeile nach dem Vorkommen der jeweils aktuellen ID in der äußeren Schleife. Das finden der ID wird durch ein Regular Expression Matching gemacht. Dazu dient die Funktion am Anfang des Scripts, die dies vereinfacht.
Das RegEx-Pattern
Mehr zu Regular Expressions findet sich zu hauf im Netz.
Wird eine ID gefunden setzt das Script die zweite Zeile nach der aktuellen mit dem Inhalt aus der Spalte hinter der ID in Excel. Dabei wird der vorhandene Text in dieser Zeile nicht gelöscht sondern eine Zeile weiter nach unten geschoben(das lässt sich anpassen wenn du das willst).
So, denke das ist erst mal genug Stoff zum verstehen für dich als Neuling in Powershell.
Grüße Uwe
alles kein Problem. Ohne weitere Informationen zu deiner Textdatei, gehe ich jetzt mal z.B. von folgendem Format deiner Textdatei aus:
version_passport = "00d6bad0-a855-11da-9c8f-000088e68a62" blablablablablablablablablablablabla
blablablabla
...
blablablabla
blablablabla
version_passport = "00d6bad0-a855-11da-9c8f-000088e68a64" dfskjfdglkjd sfglkj sdglkj dsfg
blablablabla
blablablabla
....
..
(Kommentare sind im Code abgelegt)
#Funktion zum vereinfachten Regular Expression Matching
Function Get-Matches($Pattern,$groupNumber = 0) {begin { $regex = New-Object Regex($pattern) };process { foreach ($match in ($regex.Matches($_))) { ([Object[]]$match.Groups)[$groupNumber].Value }}}
#Deine XLSX Mappe.
$ExcelMappe = "E:\Tempfolder\Scripte\test.xlsx"
#Pfad zu deiner Textdatei
$pfadTextdatei = "E:\Tempfolder\Scripte\test.txt"
$inhaltText = get-content $pfadTextdatei
echo "Excel Objekt wird unsichtbar erstellt.."
$Excel = new-object -com Excel.Application
$Excel.visible = $false
echo "Bestehende Vorlage wird geoeffnet: $ExcelMappe"
$WorkBook = $Excel.WorkBooks.open($ExcelMappe)
#Sheet 1 auswählen
$sheet = $WorkBook.Sheets.Item(1)
#Spalte in der die IDs stehen
$startColumn = 1
# Reihe in der die erste ID steht
$startRow = 1
#Anzahl der IDs
$maxRows = 10
echo "Suche nach übereinstimmenden IDs in der Textdatei"
#Starte Schleife für alle IDs
for ($i = $startRow ; $i -le $maxRows ; $i++){
#Starte Schleife über alle Zeilen der Textdatei
for ($k = 0; $k -lt $inhaltText.Length; $k++){
#Führe RegEx Pattern Matching der aktuellen Zeile in der Textdatei durch
$match = $inhaltText[$k] | Get-Matches 'version_passport = "([^\s]*)"' 1
#wenn eine passende ID gefunden wurde setze den Inhalt der zweiten Zeile mit Wert aus Spalte 2 des Excel-Sheets
#Hinweis: Der aktuelle Wert 2 Zeilen weiter in der Textdatei wird nicht überschrieben sondern in einer weiteren Zeile wieder angehängt
if($sheet.Cells.Item($i,$startColumn).Value2 -eq $match){
if ($k+1 -le $inhaltText.length){
$inhaltText[$k+1] += "`r`n" + $sheet.Cells.Item($i,$startColumn + 1).Value2
} else { #Für den Fall das eine gefundene ID in der letzen Zeile der Textdatei steht müssen wir den Text anhängen anstatt mit einem Index auf die Zeile zu verweisen
$inhaltText += "`r`n" + $sheet.Cells.Item($i,$startColumn + 1).Value2
}
}
}
}
echo "Speichere die geänderte Textdatei..."
#Speichere den veränderten Textinhalt in der selben Textdatei
set-content -Path $pfadTextdatei -Value $inhaltText
echo "Beende Excel."
#Beende Excel
$Excel.Quit()
#Beendet den Excel-Prozess, da dieser meistens trotzdem nach der 'Quit' Methode noch im Hintergrund weiter existiert (Liegt an der verzögerten COM Garbage Collection)
spps -Name Excel
echo "Fertig."
Das RegEx-Pattern
'version_passport = "([^\s]*)"'
kann man ausgespochen so verstehen:Match the characters “version_passport = "” literally «version_passport = "»
Match the regular expression below and capture its match into backreference number 1 «([^\s]*)»
Match a single character that is a “non-whitespace character” «[^\s]*»
Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the character “"” literally «"»
Wird eine ID gefunden setzt das Script die zweite Zeile nach der aktuellen mit dem Inhalt aus der Spalte hinter der ID in Excel. Dabei wird der vorhandene Text in dieser Zeile nicht gelöscht sondern eine Zeile weiter nach unten geschoben(das lässt sich anpassen wenn du das willst).
So, denke das ist erst mal genug Stoff zum verstehen für dich als Neuling in Powershell.
Grüße Uwe
#Funktion zum vereinfachten Regular Expression Matching
Function Get-Matches($Pattern,$groupNumber = 0) {begin { $regex = New-Object Regex($pattern) };process { foreach ($match in ($regex.Matches($_))) { ([Object[]]$match.Groups)[$groupNumber].Value }}}
#Deine XLSX Mappe.
$ExcelMappe = "E:\Tempfolder\Scripte\test.xlsx"
$pfadTextdatei = "E:\Tempfolder\Scripte\test.txt"
$inhaltText = get-content $pfadTextdatei
echo "Excel Objekt wird unsichtbar erstellt.."
$Excel = new-object -com Excel.Application
$Excel.visible = $false
echo "Bestehende Vorlage wird geoeffnet: $ExcelMappe"
$WorkBook = $Excel.WorkBooks.open($ExcelMappe)
#Sheet 1 auswählen
$sheet = $WorkBook.Sheets.Item(1)
#Spalte in der die IDs stehen
$startColumn = 1
# Reihe in der die erste ID steht
$startRow = 1
#Anzahl der IDs
$maxRows = 10
echo "Suche nach übereinstimmenden IDs in der Textdatei"
#Starte Schleife für alle IDs
for ($i = $startRow ; $i -le $maxRows ; $i++){
#Starte Schleife über alle Zeilen der Textdatei
for ($k = 0; $k -lt $inhaltText.Length; $k++){
#Führe RegEx Pattern Matching der aktuellen Zeile in der Textdatei durch
$match = $inhaltText[$k] | Get-Matches 'version_passport = "([^\s]*)"' 1
#wenn eine passende ID gefunden wurde setze den Inhalt drei Zeilen danach mit Wert aus Spalte 2 des Excel-Sheets
if($sheet.Cells.Item($i,$startColumn).Value2 -eq $match){
$inhaltText[$k+3] = "version_number = " + $sheet.Cells.Item($i,$startColumn + 1).Value2
}
}
}
echo "Speichere die geänderte Textdatei..."
#Speichere den veränderten Textinhalt in der selben Textdatei
set-content -Path $pfadTextdatei -Value $inhaltText
echo "Beende Excel."
#Beende Excel
$Excel.Quit()
#Beendet den Excel-Prozess, da dieser meistens trotzdem nach der 'Quit' Methode noch im Hintergrund weiter existiert (Liegt an der verzögerten COM Garbage Collection)
spps -Name Excel
echo "Fertig."
alternativ ließe sich Zeile 34 auch so schreiben, wenn sich hinter dem Gleichheitszeichen immer eine Zahl befindet:
$inhaltText[$k+3] = ($inhaltText[$k+3]) -replace "\d+", $sheet.Cells.Item($i,$startColumn + 1).Value2
Einen guten Artikel für Powershell mit dem Thema "Suchen und Ersetzen" findest du hier
Grüße Uwe