windows - slet en bestemt linje i filen med powershell

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil slette en komplet linje, der indeholder et særligt ord i en enkelt .csv-fil i et powerhell-script.


Jeg har allerede fundet arbejdskode, der sletter den specifikke linje, men skriver alle andre linjer i første linje. Dette skulle ikke ske, fordi jeg linkede csv-filen med en ms adgangstabel.


    $user = 'User2'
    $file = Get-Content c:datei.txt
    $newLine = ""

    foreach($line in $file){

        if($line -match $User){
         }else{
            $newLine += $line
        }
    }
    $newLine | Out-File c:datei.txt


Filen ser sådan ud, men med flere data og linjer:


User;computer;screen1;screen2;printer
User1;bla;bla;;bla
User2;bla;bla;bla;bla
User3;bla;bla;bla;bla


Efter kørsel af koden:


User;computer;screen1;screen2;printerUser1;bla;bla;;blaUser3;bla;bla;bla;bla


Jeg bruger Powershell 5.1.x på Windows 7

Bedste reference


Det sker, fordi du gør string sammenkædning.


$newLine = ""
$newLine += $line

# result is exactly how it looks,  
# "" -> "line1" -> "line1line2" -> "line1line2line3" ...


Den retfærdige løsning er at bruge en matrix:


$newLine = @()
$newLine += $line

# result is adding lines to an array  
# @() -> @("line1") -> @("line1","line2") -> @("line1","line2","line3") ...


men den rigtige PowerShell-måde er ikke at gøre det overhovedet, og at streame filen gennem din kode og ud i en anden fil:


$user = 'User2'
$file = Get-Content c:datei.txt

foreach($line in $file){

    if($line -match $User){
     }else{
        $line   # send the line to the output pipeline
    }

} | Out-File c:datei.txt


Men du kan vende om testen -match til -notmatch og slippe af med den tomme {} del.


$user = 'User2'
$file = Get-Content c:datei.txt

foreach($line in $file){

    if($line -notmatch $User){
        $line   # send the line to the output pipeline
    }

} | Out-File c:datei.txt


Og du kan slippe af med at gemme filindholdet midlertidigt:


$user = 'User2'
Get-Content c:datei.txt | ForEach-Object {

    if ($\_ -notmatch $User){
        $line   # send the line to the output pipeline
    }

} | Out-File c:datei.txt


Men så fungerer det kun som et filter, og du kan ændre foreach-object / if() {} for et filter [[: 17]]:


$user = 'User2'
Get-Content c:datei.txt | Where-Object {

    $\_ -notmatch $User

} | Out-File c:datei.txt


Og derefter ændre Out-file til Set-Content (parringen er get-content/set-indhold, og det giver mere kontrol over outputkodning, hvis du har brug for det):


$user = 'User2'

Get-Content c:datei.txt | 
    Where-Object { $\_ -notmatch $User } | 
    Set-Content c:datei.txt

Andre referencer 1


Du skal tilføje en 'newline' til slutningen af ​​hver tekstlinje. Skift denne linje:


$newLine += $line


til:


$newLine += "$line`r`n"