remove multiple line in file on match

Welcome Forums General PowerShell Q&A remove multiple line in file on match

Viewing 8 reply threads
  • Author
    Posts
    • #184796
      Participant
      Topics: 2
      Replies: 7
      Points: 26
      Rank: Member

      Hi PS,

      I want to clean up a file.

      im using https://psappdeploytoolkit.com for software deployment and want to cleanup a file before processing it.

      i want to remove som sections in the "Deploy-Application.ps1"

      Been using this code for some changes but this can only replace a single line at a time.

      So how could this be done?

      (Get-Content -path C:\Deploy-Application.ps1) -replace 'code1','code2'
              ## Handle Zero-Config MSI Uninstallations
              If ($useDefaultMsi) {
                  [hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Uninstall'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
                  Execute-MSI @ExecuteDefaultMSISplat
              }

      and

         ## Handle Zero-Config MSI Installations
              If ($useDefaultMsi) {
                  [hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Install'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
                  Execute-MSI @ExecuteDefaultMSISplat; If ($defaultMspFiles) { $defaultMspFiles | ForEach-Object { Execute-MSI -Action 'Patch' -Path $_ } }
              }
    • #184811
      Participant
      Topics: 1
      Replies: 1632
      Points: 3,074
      Helping Hand
      Rank: Community Hero

      Did you try to ask your question in the vendor forum https://discourse.psappdeploytoolkit.com/ ? There might be a better way of achieving what you're after instead of manipulating the code of a Powershell script with another Powershell script. 😉

    • #184847
      Participant
      Topics: 2
      Replies: 7
      Points: 26
      Rank: Member

      No haven't write in the vendor forum....

      Taking this as a learning process manipulating files. So is there a way to remove unwanted lines in a file. If you know the line number?

      I could use the "## Handle Zero-Config MSI" as a starting mark but how do I tell ps to remove the 4 lines below.

    • #184853
      Participant
      Topics: 2
      Replies: 7
      Points: 26
      Rank: Member

      activating my brain power and came up with this. Is there a better way

      $file = "\Deploy-Application.ps1"

      function del-line($start, $end, $file) {
      $i = 0
      $start–
      $end–
      (Get-Content $file) | where {
      ($i -lt $start -or $i -gt $end)
      $i++
      } > $file
      (Get-Content $file)
      }

      function LineNumber ($pattern, $file)
      {
      $LineNumber = Select-String -Path $file -Pattern $pattern | Select-Object -ExpandProperty LineNumber
      return $LineNumber
      }

      if($(LineNumber -pattern "## Handle Zero-Config MSI Installations" -file $file))
      {
      $ZeroInstallstart = LineNumber -pattern "## Handle Zero-Config MSI Installations" -file $file
      $end = $start + '5'
      del-line -start $start -end $end -file $file
      Write-Host "Installations"
      }

      if($(LineNumber -pattern "## Handle Zero-Config MSI Uninstallations" -file $file))
      {
      $start = LineNumber -pattern "## Handle Zero-Config MSI Uninstallations" -file $file
      $end = $start + '5'
      del-line -start $start -end $end -file $file
      Write-Host "Uninstallations"
      }

    • #185045
      Participant
      Topics: 1
      Replies: 1632
      Points: 3,074
      Helping Hand
      Rank: Community Hero

      If you know the line numbers you want to remove from the file I think it's easier to output the rest instead of deleting the unwanted lines ... like this:

      $file = 'Deploy-Application.ps1'
      $Start = 8
      $End = 14
      $Content = Get-Content -Path $file
      $Content[0..$($Start - 2)]
      $Content[$End .. $Content.count]

      Of course you can pipe the output to whatever further cmdlet you like. 😉

      BTW: please format you code as code like you already did in your first post in this thread. Thanks.

    • #185132
      Participant
      Topics: 2
      Replies: 7
      Points: 26
      Rank: Member

      I ended up with this solution – i only knew the comment start pattern so used that as key to match and addd 5 line to that line for removal.

      function Zero-ConfigCleanup ($file)
      {
      	function LineNumber ($pattern, $file)
      	{
      		$LineNumber = Select-String -Path $file -Pattern $pattern | Select-Object -ExpandProperty LineNumber
      		return [int]$LineNumber
      	}
      	
      	function del-line($start, $end, $file)
      	{
      		$i = 0
      		$start--
      		$end--
      		(Get-Content $file) | where {
      			($i -lt $start -or $i -gt $end)
      			$i++
      		} | set-content $file -Encoding utf8
      	}
      	
      	if ($(LineNumber -pattern "## Handle Zero-Config MSI Installations" -file $file))
      	{
      		$start = LineNumber -pattern "## Handle Zero-Config MSI Installations" -file $file
      		$end = $start + 5
      		del-line -start $start -end $end -file $file
      	}
      	
      	if ($(LineNumber -pattern "## Handle Zero-Config MSI Uninstallations" -file $file))
      	{
      		$start = LineNumber -pattern "## Handle Zero-Config MSI Uninstallations" -file $file
      		$end = $start + 5
      		del-line -start $start -end $end -file $file
      	}
      }
      
    • #185135
      Participant
      Topics: 2
      Replies: 7
      Points: 26
      Rank: Member

      If you know the line numbers you want to remove from the file I think it's easier to output the rest instead of deleting the unwanted lines ... like this:

      PowerShell
      6 lines

      1
      2
      3
      4
      5
      6
      $file = 'Deploy-Application.ps1'
      $Start = 8
      $End = 14
      $Content = Get-Content Path $file
      $Content[0..$($Start 2)]
      $Content[$End .. $Content.count]
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

      Of course you can pipe the output to whatever further cmdlet you like. 😉

      BTW: please format you code as code like you already did in your first post in this thread. Thanks.

      Yours looks alot simpler than mine...can you explain what happen in these to lines

      $Content[0..$($Start - 2)]
      $Content[$End .. $Content.count]

      if i wanted the modified text with your way i could pipe it out like this?

      $Content | Set-content $file -Encoding utf8
      
    • #185147
      Participant
      Topics: 1
      Replies: 1632
      Points: 3,074
      Helping Hand
      Rank: Community Hero

      Yours looks alot simpler than mine...can you explain what happen in these to lines

      That was the purpose. 😉 You can output any element of an array by using its index.

      $array = 1, 2, 3, 4, 5, 6, 7, 8,9,10
      $array[5]

      Please notice the index of an array starts with 0.
      If you like to output a range of consecutive items from the array you can use the range operator like this:

      $array[3..8]

      Instead of providing the index explicitly you can use variables like this

      $Start = 3
      $end = 8
      $array[$Start .. $end]

      And because the index is an integer you can calculate with it. 😉

      if i wanted the modified text with your way i could pipe it out like this?

      With Set-Content you would replace the already existing content of a given file. If you have two chunks of lines you want to concatenate you would replace the first chunk with the second one.
      I'd recommend creating an new file and using Out-File with the parameter -Append for the second chunk or Add-Content.

      $array[0..$($Start - 1)] | Out-File -FilePath 'NewFile.txt' -Encoding utf8
      $array[$($End + 1) .. $array.count] | Out-File -FilePath 'NewFile.txt' -Encoding utf8 -Append

      Of course there are – as always – a few different ways to achieve a certain goal ...

      $array[0..$($Start - 1)] + $array[$($End + 1) .. $array.count] | Out-File -FilePath 'NewFile.txt' -Encoding utf8

      ... or ...

      $NewContent = $array[0..$($Start - 1)] + $array[$($End + 1) .. $array.count] 
      $NewContent | Out-File -FilePath 'NewFile.txt' -Encoding utf8

      .... 😉

    • #185150
      Participant
      Topics: 4
      Replies: 95
      Points: 192
      Helping Hand
      Rank: Participant

      This was interesting. Few things I would maybe add would be the option to choose output format or check what the current file is and use that.

      I came up with this function

      
      function Remove-DuplicateRowsFromFile
      {
      [CmdletBinding(SupportsShouldProcess=$true,
      PositionalBinding=$false,
      ConfirmImpact='Medium')]
      Param
      (
      # FilePath
      [Parameter(Mandatory=$true,
      ValueFromPipeline=$true,
      ValueFromPipelineByPropertyName=$true,
      ValueFromRemainingArguments=$false,
      Position=0)]
      [ValidateNotNull()]
      [ValidateNotNullOrEmpty()]
      $FilePath,
      
      # Pattern to remove
      [Parameter(Mandatory=$true,
      ValueFromPipeline=$true,
      ValueFromPipelineByPropertyName=$true,
      ValueFromRemainingArguments=$false,
      Position=1)]
      [ValidateNotNull()]
      [ValidateNotNullOrEmpty()]
      [string]
      $Pattern
      )
      
      Begin
      {
      }
      Process
      {
      
      $duplicateRows = select-String -Path $file -Pattern $line | select -Skip 1
      $rowNumber = 0
      
      $outContent = foreach ($row in (Get-Content $file))
      {
      $rowNumber++
      if ($duplicateRows.linenumber -contains $rowNumber)
      {
      if ($pscmdlet.ShouldProcess("Skipping row", $rowNumber))
      {
      continue
      }
      } #if
      else
      {
      $row
      } #else
      }
      
      } #process
      End
      {
      if ($pscmdlet.ShouldProcess("Save file", $file))
      {
      $outContent | Out-File $FilePath -Encoding utf8
      }
      } #end
      }
      
      
Viewing 8 reply threads
  • You must be logged in to reply to this topic.