Reputation: 21
I want to delete a complete line which contains a special word in a single .csv file in a powershell script.
I already found working code, that deletes the specific line, but writes all other lines into the first line. This shouldn't happen, because I linked the csv-file with an ms access table.
$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
The file looks like this, but with more data and lines:
User;computer;screen1;screen2;printer
User1;bla;bla;;bla
User2;bla;bla;bla;bla
User3;bla;bla;bla;bla
After running the code:
User;computer;screen1;screen2;printerUser1;bla;bla;;blaUser3;bla;bla;bla;bla
I use Powershell 5.1.x on Windows 7
Upvotes: 2
Views: 5878
Reputation: 28993
It happens because you're doing string concatenation.
$newLine = ""
$newLine += $line
# result is exactly how it looks,
# "" -> "line1" -> "line1line2" -> "line1line2line3" ...
The straightforward fix is to use an array:
$newLine = @()
$newLine += $line
# result is adding lines to an array
# @() -> @("line1") -> @("line1","line2") -> @("line1","line2","line3") ...
but the proper PowerShell way is not to do that at all, and to stream the file through your code and out into another file:
$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
But you can invert the test -match
to -notmatch
and get rid of the empty {}
part.
$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
And you can get rid of temporarily storing the file content:
$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
But then it's just acting as a filter, and you can change foreach-object / if() {}
for a where-object
filter:
$user = 'User2'
Get-Content c:\datei.txt | Where-Object {
$_ -notmatch $User
} | Out-File c:\datei.txt
And then change Out-file
for Set-Content
(the pairing is get-content/set-content, and it gives more control over output encoding if you need it):
$user = 'User2'
Get-Content c:\datei.txt |
Where-Object { $_ -notmatch $User } |
Set-Content c:\datei.txt
Upvotes: 6
Reputation: 8432
You need to add a 'newline' to the end of each line of text. Change this line:
$newLine += $line
to:
$newLine += "$line`r`n"
Upvotes: 0