Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Powershell Datei einlesen, Datensätze mit anderer Datei vergleichen und ändern

Frage Entwicklung Batch & Shell

Mitglied: christianrutz

christianrutz (Level 1) - Jetzt verbinden

20.08.2013 um 11:10 Uhr, 5630 Aufrufe, 9 Kommentare, 4 Danke

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!
Mitglied: Pope35i
20.08.2013 um 14:21 Uhr
Hallo,
ich arbeite mich auch gerade in PowerShell ein, eine Verbindung zum Excel habe ich schonmal.

Das funktioniert so:


01.
$ExcelMappe = "C:\xxxx\NeueTestMappe.xlsx" #Deine XLSX Mappe. 
02.
 
03.
#Excel Objekt wird erstellt 
04.
echo "Excel Objekt wird erstellt.." 
05.
$Excel = new-object -comobject Excel.application 
06.
$Excel.visible = $True 
07.
 
08.
 
09.
# Öffnet bestehende Excel Datei 
10.
echo "Bestehende Vorlage wird geoeffnet: $ExcelMappe" 
11.
$WorkBook = $Excel.WorkBooks.open($ExcelMappe) 
12.
$Sheet = $WorkBook.ActiveSheet 
13.
$cells=$Sheet.Cells 
14.
 
15.
#Spalte und Zeile Definieren 
16.
$Spalte = 1 
17.
$Zeile = 1 
18.
 
19.
# Zum Auslesen der Felder: 
20.
$feld_inhalt = $Cells.Item($Spalte,$Zeile).value2 
21.
 
22.
#Zum Ausgeben (Ob alles geklappt hat) 
23.
$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.
Bitte warten ..
Mitglied: christianrutz
20.08.2013 um 14:39 Uhr
Hi,
wow das ging ja schnell! Danke für die schnelle Antwort!
Hilft mir auf jedenfall schon etwas weiter. das ganze kann ich ja beliebig oft wiederholen lassen um die ganzen einträge der Spalte abzuarbeiten. (sind ca 10 Einträge)

Nun muss ich nurnoch wissen wie ich das mit den Zeilen bzw einträgen einer .txt datei vergleiche, wäre ja nicht so schwer wenn nicht das Problem wäre das in der .txt vor und hinter dem Wert der mich interessiert noch andere Sachen stehen. Bsp.
version_passport = "00d6bad0-a855-11da-9c8f-000088e68a62"
zum vergleichen interessiert mich aber nur diese Nummer (da auch nur diese Nummer in der xls Datei steht.
00d6bad0-a855-11da-9c8f-000088e68a62

Das weitere Problem:
Nach dem Vergleich (vorrausgestzt die Nummer stimmen überein) Soll ein Eintrag aus der 2. Spalte der Excel Tabelle, 2 Zeilen unter dieser Nummer in der .txt geschrieben werden.
Ich hoffe auf weitere Hilfen.

Danke!
Bitte warten ..
Mitglied: Pope35i
20.08.2013 um 16:22 Uhr
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.
Bitte warten ..
Mitglied: colinardo
20.08.2013, aktualisiert um 18:29 Uhr
Hallo christianrutz,
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 
.... 
..
Dann kannst du mit folgendem Code arbeiten:
(Kommentare sind im Code abgelegt)
01.
#Funktion zum vereinfachten Regular Expression Matching 
02.
Function Get-Matches($Pattern,$groupNumber = 0) {begin { $regex = New-Object Regex($pattern) };process { foreach ($match in ($regex.Matches($_))) { ([Object[]]$match.Groups)[$groupNumber].Value }}} 
03.
 
04.
#Deine XLSX Mappe. 
05.
$ExcelMappe = "E:\Tempfolder\Scripte\test.xlsx"  
06.
#Pfad zu deiner Textdatei 
07.
$pfadTextdatei = "E:\Tempfolder\Scripte\test.txt" 
08.
$inhaltText = get-content $pfadTextdatei 
09.
 
10.
echo "Excel Objekt wird unsichtbar erstellt.." 
11.
$Excel = new-object -com Excel.Application 
12.
$Excel.visible = $false 
13.
 
14.
echo "Bestehende Vorlage wird geoeffnet: $ExcelMappe" 
15.
$WorkBook = $Excel.WorkBooks.open($ExcelMappe) 
16.
#Sheet 1 auswählen 
17.
$sheet = $WorkBook.Sheets.Item(1) 
18.
 
19.
#Spalte in der die IDs stehen 
20.
$startColumn = 1 
21.
# Reihe in der die erste ID steht 
22.
$startRow = 1 
23.
#Anzahl der IDs 
24.
$maxRows = 10 
25.
 
26.
echo "Suche nach übereinstimmenden IDs in der Textdatei" 
27.
#Starte Schleife für alle IDs 
28.
for ($i = $startRow ; $i -le $maxRows ; $i++){ 
29.
    #Starte Schleife über alle Zeilen der Textdatei 
30.
    for ($k = 0; $k -lt $inhaltText.Length; $k++){ 
31.
        #Führe RegEx Pattern Matching der aktuellen Zeile in der Textdatei durch 
32.
        $match = $inhaltText[$k] | Get-Matches 'version_passport = "([^\s]*)"' 1 
33.
        #wenn eine passende ID gefunden wurde setze den Inhalt der zweiten Zeile mit Wert aus Spalte 2 des Excel-Sheets 
34.
        #Hinweis: Der aktuelle Wert 2 Zeilen weiter in der Textdatei wird nicht überschrieben sondern in einer weiteren Zeile wieder angehängt 
35.
        if($sheet.Cells.Item($i,$startColumn).Value2 -eq $match){ 
36.
            if ($k+1 -le $inhaltText.length){ 
37.
                $inhaltText[$k+1] +=  "`r`n" + $sheet.Cells.Item($i,$startColumn + 1).Value2 
38.
            } 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 
39.
                $inhaltText +=  "`r`n" + $sheet.Cells.Item($i,$startColumn + 1).Value2 
40.
41.
        }  
42.
43.
44.
echo "Speichere die geänderte Textdatei..." 
45.
#Speichere den veränderten Textinhalt in der selben Textdatei 
46.
set-content -Path $pfadTextdatei -Value $inhaltText 
47.
 
48.
echo "Beende Excel." 
49.
#Beende Excel 
50.
$Excel.Quit() 
51.
 
52.
#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) 
53.
spps -Name Excel 
54.
echo "Fertig."
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 '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 «"»
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
Bitte warten ..
Mitglied: christianrutz
21.08.2013 um 08:56 Uhr
Hallo,

erstmal vielen vielen Dank für diese superschnelle und echt großartige Antwort! Dieses Forum ist wirklich wahnsinnig gut!

Die Antwort hat mich schon viel weiter gebracht!

Die Textatei sieht wie folgt aus:


version = {
project = ""
library = ""
item_passport = "1134817842:937482499:1533"
version_passport = "00d6bad0-a855-11da-9c8f-000088e68a62"
type = "LIB PART"
intent = "reference"
version_number = 5
filename = "1215499_0119.prt"
name = "Scheibe Unterleg 5.3 DIN 125 A2"
part_number = "T1215499"
revision = "005"
version = {
project = ""
library = ""
item_passport = "1134817842:937482499:1533"
version_passport = "00d6bad0-a855-11da-9c8f-000088e68a62"
type = "LIB PART"
intent = "reference"
version_number = 5
filename = "1215499_0119.prt"
name = "Scheibe Unterleg 5.3 DIN 125 A2"
part_number = "T1215499"
revision = "005"

usw....

Wie oben beschrieben soll der eintrag "version_passport = "....." verglichen werden.

Funktioniert wunderbar!

Ersetzt werden soll:
version_number = 5
in diesem Fall steht in der Excel Tabelle z.B. eine 6
Das Ergebniss heißt dann:
version_number = 6

Wie sage ich ihm das er nur die Zahl ersetzen soll und nicht komplett alles?

Vielen Dank schonmal!
Bitte warten ..
Mitglied: colinardo
21.08.2013, aktualisiert um 09:34 Uhr
01.
#Funktion zum vereinfachten Regular Expression Matching 
02.
Function Get-Matches($Pattern,$groupNumber = 0) {begin { $regex = New-Object Regex($pattern) };process { foreach ($match in ($regex.Matches($_))) { ([Object[]]$match.Groups)[$groupNumber].Value }}} 
03.
 
04.
#Deine XLSX Mappe. 
05.
$ExcelMappe = "E:\Tempfolder\Scripte\test.xlsx"  
06.
$pfadTextdatei = "E:\Tempfolder\Scripte\test.txt" 
07.
$inhaltText = get-content $pfadTextdatei 
08.
 
09.
echo "Excel Objekt wird unsichtbar erstellt.." 
10.
$Excel = new-object -com Excel.Application 
11.
$Excel.visible = $false 
12.
 
13.
echo "Bestehende Vorlage wird geoeffnet: $ExcelMappe" 
14.
$WorkBook = $Excel.WorkBooks.open($ExcelMappe) 
15.
#Sheet 1 auswählen 
16.
$sheet = $WorkBook.Sheets.Item(1) 
17.
 
18.
#Spalte in der die IDs stehen 
19.
$startColumn = 1 
20.
# Reihe in der die erste ID steht 
21.
$startRow = 1 
22.
#Anzahl der IDs 
23.
$maxRows = 10 
24.
 
25.
echo "Suche nach übereinstimmenden IDs in der Textdatei" 
26.
#Starte Schleife für alle IDs 
27.
for ($i = $startRow ; $i -le $maxRows ; $i++){ 
28.
    #Starte Schleife über alle Zeilen der Textdatei 
29.
    for ($k = 0; $k -lt $inhaltText.Length; $k++){ 
30.
        #Führe RegEx Pattern Matching der aktuellen Zeile in der Textdatei durch 
31.
        $match = $inhaltText[$k] | Get-Matches 'version_passport = "([^\s]*)"' 1 
32.
        #wenn eine passende ID gefunden wurde setze den Inhalt drei Zeilen danach mit Wert aus Spalte 2 des Excel-Sheets 
33.
        if($sheet.Cells.Item($i,$startColumn).Value2 -eq $match){ 
34.
            $inhaltText[$k+3] =  "version_number = " + $sheet.Cells.Item($i,$startColumn + 1).Value2 
35.
        }  
36.
37.
38.
echo "Speichere die geänderte Textdatei..." 
39.
#Speichere den veränderten Textinhalt in der selben Textdatei 
40.
set-content -Path $pfadTextdatei -Value $inhaltText 
41.
 
42.
echo "Beende Excel." 
43.
#Beende Excel 
44.
$Excel.Quit() 
45.
 
46.
#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) 
47.
spps -Name Excel 
48.
echo "Fertig."
alternativ ließe sich Zeile 34 auch so schreiben, wenn sich hinter dem Gleichheitszeichen immer eine Zahl befindet:
01.
 $inhaltText[$k+3] = ($inhaltText[$k+3])  -replace "\d+", $sheet.Cells.Item($i,$startColumn + 1).Value2
dann dürfte sich auch der Text **version_number" beliebig ändern.

Einen guten Artikel für Powershell mit dem Thema "Suchen und Ersetzen" findest du hier

Grüße Uwe
Bitte warten ..
Mitglied: christianrutz
21.08.2013 um 09:41 Uhr
Hi,

echt stark! Vielen Dank!

Jetzt nurnoch etwas zum Verständniss.

Bei der Suche in der Excel Datei wird festgelegt wo die einträge genau stehen:

#Spalte in der die IDs stehen
$startColumn = 1
  1. Reihe in der die erste ID steht
$startRow = 1
#Anzahl der IDs
$maxRows = 10


Wo genau wird das beim ersetzen gesagt also das er die 2. Spalte nehmen soll. Die erste Zahl die ersetzt werden soll steht quasi in Spalte 2, Zeile 2.

Ich kann nicht genau rauslesen wo ich das festlege.

Danach müsste alles super sein.

Vielen Dank!
Bitte warten ..
Mitglied: colinardo
21.08.2013 um 09:45 Uhr
In Zeile 34 im Code:
$sheet.Cells.Item($i,$startColumn + 1).Value2
zu $startColumn wird eine 1 addiert.
Wenn deine ID also zum Beispiel in Spalte A steht und deine Werte in Spalte C addierst du 2 dazu.

Viel Erfolg
Uwe
Bitte warten ..
Mitglied: christianrutz
21.08.2013 um 10:28 Uhr
Dieses Forum ist absolut Top und empfehlenswert! Jetzt verstehe ich es!

Vielen Dank an euch! Besonderen Dank an colinardo / Uwe!
Bitte warten ..
Neuester Wissensbeitrag
CPU, RAM, Mainboards

Angetestet: PC Engines APU 3a2 im Rack-Gehäuse

(2)

Erfahrungsbericht von ashnod zum Thema CPU, RAM, Mainboards ...

Ähnliche Inhalte
Batch & Shell
gelöst Powershell Datei kopieren mit ACL Script funktioniert nicht (4)

Frage von xpxy15 zum Thema Batch & Shell ...

Batch & Shell
gelöst Powershell - Dateien aus verschiedenen Arrays - Attribute vergleichen (5)

Frage von Giffas zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Switche und Hubs
Trunk für 2xCisco Switch. Wo liegt der Fehler? (15)

Frage von JayyyH zum Thema Switche und Hubs ...

DSL, VDSL
DSL-Signal bewerten (13)

Frage von SarekHL zum Thema DSL, VDSL ...

Backup
Clients als Server missbrauchen? (10)

Frage von 1410640014 zum Thema Backup ...