none
split bei ; wenn nicht in ";" RRS feed

  • Frage

  • Hallo,

    ich soll eine .csv datei einlesen. Als trennzeichen sind ; gesetzt. Wenn allerdings im Text selber ; vorhanden sind, ist um die Zeile "

    Beispiel:

    Test;Hallo;"langer satz mit; und so";Langer Satz ohne;...

    Bis jetzt sieht es so aus, funktioniert auch bis auf die Sache mit den Semikolon innerhalb der Anführungszeichen.

            $file = Get-Content $Directory\$filename
            foreach ($row in $file){
                $erg=$row -split ";"
            }

    Wie überspringe ich jetzt die Semikolons innerhalb der Anführungszeichen?

    lg Zuyas

    Montag, 6. Mai 2013 11:42

Antworten

  • Etwa so!? :

    # Wenn man eine CSV in einer ForEach Schleife benutzen möchte, ist es unsinn # diese erst in eine Variable zu packen! # Benutzt Import-CSV direkt in der ForEach schleife, das spart speicher # und einen zwischenschritt! # CSV Datei einlesen und jedes Zeile (Objekt) durchlaufen ForEach ($User in Import-CSV D:\temp\Users.csv) { # Jedes Property in dem aktuellen Objekt durchlaufen ForEach ($Property in $User.psobject.Properties){ # Bei CSV Objekten sind nur NoteProperty Interessant! If($Property.MemberType -eq 'NoteProperty') { # Anzeigen des Namens und des Wertes der CSV-Spalte (Property) "Das Property: {0} hat den Wert: {1}" -f $Property.Name, $Property.Value } } }



    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!


    • Bearbeitet Peter Kriegel Dienstag, 7. Mai 2013 15:19
    • Als Antwort markiert Zuyas Mittwoch, 8. Mai 2013 11:26
    Dienstag, 7. Mai 2013 15:18

Alle Antworten

  • Hallo Zuyas,

    Verwende  direkt das cmdlet Import-CSV dann musst du dich um das Splitten deiner CSV nicht kümmern.

    Viele Grüße,


    Philipp Halbedel

    MCP 2003,MCITP EA Server 2008,MCITP EA Windows 7,MCSA2008,MCSA2012 

    Meine Antwort war hilfreich? ich freu mich über eine Bewertung. If my answer was helpful, I'm glad about a rating! 

    I do not represent the organisation I work for, all the opinions expressed here are my own.

    Montag, 6. Mai 2013 11:48
  • Hallo Philipp,

    danke für die schnelle Antwort. Leider funktioniert es mit Import-CSV nicht so wie ich es mir vorstelle. Kommt z.B. ein Komma im Satz vor, bricht es einfach ab.

    Ziel meines Skriptes ist es übrigens die Daten aus der csv in eine Datenbank zu schreiben. bis jetzt sieht es so aus:

    function insertdata([string]$filename){
        $shortfilename=$filename.split(".")[0]
        $file = Get-Content $Directory\$filename
        [int]$checkfirst=1
        foreach ($row in $file){
            $erg=$row -split(';')
            if($checkfirst -eq 1){
                $head= "INSERT INTO "+$shortfilename+" ("
                foreach ($hrow in $erg){
                    $head+='['+$hrow+'],'
                }
                $head = $head.Substring(0, $head.Length-1)
                $head+=")"
            }else{
            
                $tail= " VALUES ("
                foreach ($trow in $erg){
                    $tail+="'"+$trow.Replace("'","").Replace('"','')+"',"            
                }
                $tail = $tail.Substring(0, $tail.Length-1)
                $tail+=")"
            
                $SQLServer = "XXX"
                $SQLDBName = "XXX"
                $SqlQuery = $head+$tail
                $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
                $SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; Integrated Security = True" 
                $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
                $SqlCmd.CommandText = $SqlQuery
                $SqlCmd.Connection = $SqlConnection 
                $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
                $SqlAdapter.SelectCommand = $SqlCmd 
                $DataSet = New-Object System.Data.DataSet
                $importerror=0
            	try
            	{
            		$SqlAdapter.Fill($DataSet)| Out-Null 
            	}
            	catch
            	{
                    $error=$_.Exception.Message.Replace("'","").Replace('"','')
                    importlog -filename $filename -importtype " " -message $error -msgtype "ERROR(LINE)"
                    $global:counterror+=1
                    $importerror=1
            	}
                
                if($importerror -eq 0){
                    $global:countsuccess+=1
                }
                $global:counttotal+=1
                $SqlConnection.Close() 
            }
            $checkfirst=0
        }
    }

    Und ich weiß leider nicht wie ich es da mit Import-CSV besser hinbekommen kann.

    lg Zuyas

    Montag, 6. Mai 2013 12:39
  • Hallo Zuyas,

    Der Grund ist das der Seperator per default das Komma ist.

    Versuch doch mal 

    $file = Import-CSV $Directory\$filename -Delimiter ";"

    Die Funktion ist wirklich klasse, da die Manipulation anschließend wirklich sehr einfach ist.

    Viele Grüße


    Philipp Halbedel

    MCP 2003,MCITP EA Server 2008,MCITP EA Windows 7,MCSA2008,MCSA2012 

    Meine Antwort war hilfreich? ich freu mich über eine Bewertung. If my answer was helpful, I'm glad about a rating! 

    I do not represent the organisation I work for, all the opinions expressed here are my own.

    Montag, 6. Mai 2013 13:05
  • Hallo Philipp,

    das habe ich auch im selben moment wie Sie es schrieben herausgefunden, funktioniert auch super!

    Nur wie kann ich das jetzt auf meinen "$head  / $tail" teil anwenden?

    Wenn ich es mit:

    $file = Import-Csv D:\LOGINventory5\scripts\value2db\import\person.csv -delimiter ";" 
    foreach ($erg in $file){
        $erg
    }

    mache bekomme ich folgendes:

    ID                 : XXXXX
    LastName             : YY YYYYYY
    FirstName            : ZZZZZZZ
    Title                : Herr
    DisplayName          : AA AAAAAA, AAAA

    ...usw.

    Wie bekomme ich jetzt "ID","LastName","FirstName"... und "XXXXX","YY YYYYYY",.... um es so in die Datenbank zu schreiben?

    lg Zuyas


    PS. Ohne zu sagen $erg.ID oder $erg.LastName etc.. Es ist nämlich eine Funktion wo mehrere csv dateien durch gehen und die haben nicht alle  "ID","LastName","FirstName"...
    • Bearbeitet Zuyas Montag, 6. Mai 2013 13:25 Genauere Beschreibung
    Montag, 6. Mai 2013 13:22
  • Wir dutzen uns hier alle :)

    Wenn du mehrere CSV´s hat welche einen unterschiedlichen Aufbau haben musst du entweder für jede CSV ein eigenes Script schreiben oder versuchen irgendwie die CSV´s gleich zu stellen.

    Du kannst auf jedenfall deinen SQL string wie folgt zuammenbauen...

    $meinString = "SELECT $($erg.ID) FROM $($erg.LastName) WHERE .....usw"

    Viele Grüße,


    Philipp Halbedel

    MCP 2003,MCITP EA Server 2008,MCITP EA Windows 7,MCSA2008,MCSA2012 

    Meine Antwort war hilfreich? ich freu mich über eine Bewertung. If my answer was helpful, I'm glad about a rating! 

    I do not represent the organisation I work for, all the opinions expressed here are my own.

    Montag, 6. Mai 2013 13:40
  • Alles klar ;)

    Gibt es denn keine möglichkeit diese Blöcke nochmal mit einer Schleife durchzugehen?

    Also sowas wie (wunschcode):

    $file = Import-Csv D:\LOGINventory5\scripts\value2db\import\person.csv -delimiter ";" 
    foreach ($erg in $file){
        foreach ($value in $erg){
            $value[0] #enthält ID, danach LastName, FirstName....
            $value[1] #enthält XXXXX, danach YY YYYYYY....
        }
    }

    Denn die Dateien gleich zu stellen ist unmöglich, da sie vollkommen andere Inhalte haben (werden auch in andere Tabellen der Datenbank eingetragen).

    Und die Abfrage mit vorgegebenen Zellennamen zu machen würde ewig dauern, nach DisplayName folgen noch ca. 100 weitere (pro Datei).

    lg Zuyas

    Montag, 6. Mai 2013 13:57
  • Etwa so!? :

    # Wenn man eine CSV in einer ForEach Schleife benutzen möchte, ist es unsinn # diese erst in eine Variable zu packen! # Benutzt Import-CSV direkt in der ForEach schleife, das spart speicher # und einen zwischenschritt! # CSV Datei einlesen und jedes Zeile (Objekt) durchlaufen ForEach ($User in Import-CSV D:\temp\Users.csv) { # Jedes Property in dem aktuellen Objekt durchlaufen ForEach ($Property in $User.psobject.Properties){ # Bei CSV Objekten sind nur NoteProperty Interessant! If($Property.MemberType -eq 'NoteProperty') { # Anzeigen des Namens und des Wertes der CSV-Spalte (Property) "Das Property: {0} hat den Wert: {1}" -f $Property.Name, $Property.Value } } }



    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!


    • Bearbeitet Peter Kriegel Dienstag, 7. Mai 2013 15:19
    • Als Antwort markiert Zuyas Mittwoch, 8. Mai 2013 11:26
    Dienstag, 7. Mai 2013 15:18
  • Genau so!

    Vielen vielen Dank! Ihr habt mir beide sehr geholfen!

    Mittwoch, 8. Mai 2013 11:28