2016-05-24 12 views
1

Ich überprüfe eine Datei nach Zeilen, in denen ein Char in einer speziellen Position fehlt. Wenn das Zeichen fehlt, füge ich es an genau diesem Ort ein. Jetzt möchte ich diese neue Zeile mit dem zusätzlichen Zeichen über die alte Zeile in die Datei schreiben. Zum Beispiel habe ich im Anschluss an die in der Datei:Powershell - Ersetzen Sie einige Zeilen

"C:\\path\test\test" 
"C:\\path\test\test2\" 
"C:\\path\test\test3\" 

Nachdem ich mein kurzes Skript laufen, will ich es wie folgt aussehen:

"C:\path\test\test\" 
"C:\path\test\test2\" 
"C:\path\test\test3\" 

Ich versuche zu erreichen, dass diese kleine Schleife:

$content = Get-Content C:\path\to\file.txt 
foreach ($line in $content) 
{ 
    if($line[-25] -ne '\') { 
     $test = $line -replace '(?<!\\)(?=.{24}$)', '\' | Set-Content C:\path\to\file.txt 
    } 
    else { 
     continue 
    } 
} 

Dieser Code fügt mir das Zeichen an der richtigen Stelle ein. Aber am Ende ist nur Zeile eins in der Datei, statt aller drei Zeilen. Ich denke, ich bin in der Nähe, aber erst mit Powershell gestartet.

Antwort

2

Set-Content ersetzt den gesamten Inhalt einer Datei durch die Eingabewerte. Sie rufen es unabhängig bei jeder Iteration der Schleife auf, wenn Sie es wirklich mit allen Ergebnissen der Schleife aufrufen wollen.

Es gibt viele Möglichkeiten, es zu ändern, aber ich hielte foreach mit ForEach-Object ersetzen und Rohrleitungen das Ergebnis in Set-Content:

Get-Content C:\path\to\file.txt | 
ForEach-Object -Process { 
    $line = $_ 
    if($line[-25] -ne '\') { 
     $line -replace '(?<!\\)(?=.{24}$)', '\' 
    } else { 
     $line 
    } 
} | Set-Content C:\path\to\file.txt 
+1

Danke, funktioniert perfekt! Für alle anderen, die ein ähnliches Problem haben, setzen Sie den 'Get-Content C: \ Pfad \ zu \ Datei.txt' in Klammern' (Get-Content C: \ Pfad \ zu \ Datei.txt) '. Andernfalls kann der Set-Content nicht auf die Datei zugreifen, da diese noch von Get-Content verwendet wird. – BallerNacken

+2

@BallerNacken guter Punkt; Sie könnten auch in eine separate Datei schreiben, die es tun würde. – briantist

2

Wie @briantist weist darauf hin, müssen Sie die Set-Content außerhalb der Bewegung für Schleife, um die gesamte Datei auf einmal zu setzen. Innerhalb der for-Schleife ist jedoch keine Zeichenzählung erforderlich. Und ich finde, es ist besser, die System-APIs zu verwenden, um mit Pfaden zu arbeiten, anstatt zu versuchen, eine Regex zu schreiben.

Get-Content $inputFileName | Foreach-Object { 
    # Strip quotes 
    $line = $_ -replace '"','' 

    # Add trailing backslash if needed 
    $line += '\' 

    # Call .NET GetFullPath to normalize. This removes double backslashes 
    # and resolves relative paths if needed. 
    $line = [System.IO.Path]::GetFullPath($line) 

    # Add quotes back, and output string 
    '"' + $line + '"' 
} | Set-Content $outputFileName 

Oder in viel komprimierter Form

gc $inputFile | % { [io.path]::GetFullPath((($_+'\') -replace '"','')) } | sc $outputFile 
+0

Ich akzeptierte Briantists Antwort, aber wird Ihre betrachten und es testen. Danke! – BallerNacken

+0

@BallerNacken sollten Sie definitiv Pfadfunktionen und Cmdlets ('Split-Path',' Join-Path') in Betracht ziehen, anstatt was Sie vorher gemacht haben. – briantist