简体   繁体   中英

Delete multiple lines in a text file using Powershell

I have a text file like below:

[Option]
DuplicateUncoveredDiff = 1
KeptPatternMaxCount = 7

[6107]
CtrlFlag = 10
Version =1532

[6900]
CtrlFlag = 10
Version =1532

...and some more text here

I am trying to find a way to delete multiple lines under a group. When I say group, I am referring to the strings inside [ ] brackets and whatever is under it.

For example, this is Group 1:

[Option]
DuplicateUncoveredDiff = 1
KeptPatternMaxCount = 7

Group 2:

[6107]
CtrlFlag = 10
Version =1532

Is there a way to remove the lines [Group 2]? Take note that line number or range cannot be used as this text file is not static.

So what I did, I parsed all the strings, replaced newline with "@" and looked for the value 6107 using -like operator, copied the content to another text file. But what I would like to achieve is instead of selecting the group, I would like to deselect it - selecting all other lines except 6107 group. I tried playing with the replace, putting the wildcard after 6107] and before the first occurrence of [ but it deleted everything.

$content = Get-Content $filePath\$fileName -Raw
$content -replace "`n|`r", "@" | Set-Content $localPath\$newFile

$newContent = Get-Content $localPath\$newFile

if($newContent -like "*6107*")
{
$newContent -replace ".*6107]","" -replace "\[.*","" | Set-Content 
"$folderPath\6107.txt"
}

Please help. TIA!

Since you seem to have trouble with regex, let's try if we can do it without. (There are many threads here on what you did wrong, so I don't want to go into this, plus it's always good to be keep in mind that most of the time there is more than one way to do something.)

You have some lines of text, and for each of them you want to decide if you want to keep it or not, like this:

keep   [Option]
keep   DuplicateUncoveredDiff = 1
keep   KeptPatternMaxCount = 7
keep   
       [6107]
       CtrlFlag = 10
       Version =1532

keep   [6900]
keep   CtrlFlag = 10
keep   Version =1532
keep   
keep   ...and some more text here

So assuming we go through the text line-wise, what we need is a "keep" flag that is $true by default and flips to $false when "[6107]" is encountered, and back to $true again when the next "[" comes up. This flag can then be used to filter the lines.

We can use the Where-Object cmdlet to keep track of the flag and filter the lines:

$keep = $true
Get-Content yourtextfile.txt | where { 
  if ( $_.StartsWith("[6107]") ) {
    $keep = $false
  } elseif ( -not $keep -and $_.StartsWith("[") ) {
    $keep = $true
  }
  $keep
}

Get-Content splits the text file into lines for you already, so we can pipe them right to Where-Object .

Note how $keep flips to $false and stays $false until the next line starting with "[" .

You can pipe the result of that right to Set-Content to write it to a new file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM