Patrick Brandt
Patrick Brandt

Reputation: 17

powershell replace and delete

I need the code to find the string 1234 using the marker ====-, then replace #### with the 1234, then delete the line ====-1234.

The text file can have one group (Sample Text A):

A;1;1;####;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
====-1234

Or multiple groups (Sample Text B):

A;1;1;####;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
====-1234
A;1;1;####;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
====-5678

The code as of right now deletes everything in the text file. Any help?

$regex = 
@'
(?ms)(.+?####;
.+?)
====-(\d+)
'@

Get-Childitem -Path C:\somedir -Filter *.txt |
  foreach {

    $text = Get-Content $_ 

    ([regex]::matches($text,$regex) |
      foreach {
        $_.groups[1].value -replace '####',($_.groups[2].value)
      }) -join '' |
      Set-Content $_.FullName
  }

Upvotes: 1

Views: 234

Answers (2)

mjolinor
mjolinor

Reputation: 68273

This appears to be a continuation of an earlier question I had provided an answer to, but that solution relied on using the -Raw parameter of Get-Content and you're apparently running V2. Beyond that the posted data has changed from the original question, so that solution wouldn't have worked anyway.

Here's an updated version, adjusted for the new data criteria and compatible with V2:

$regex = 
@'
(?ms)(.+?####;.+?
.+?)
====-(\d+)
'@

$Files = 
Get-Childitem -Path C:\somedir -Filter *.txt 

foreach ($file in $files)
 {
    $Text = Get-Content $file.fullname | out-string 

    ([regex]::matches($text,$regex) |
    foreach {
    $_.groups[1].value -replace '####',($_.groups[2].value)
    }) -join '' |
    Set-Content $file.fullname
 }

Upvotes: 1

arco444
arco444

Reputation: 22831

You might benefit from using an ArrayList in this scenario. The following approach iterates over the file and notes the positions when either #### or ====- are encountered.

It can then modify the contents at those positions by firstly directly replacing the contents at the index where #### was found, and secondly by using the removeAt method of ArrayList to delete the entries where ====- was encountered:

[System.Collections.Arraylist]$t = Get-Content .\sampleb.txt
$removeAt = @()

$i = 0
while($i -lt $t.count) {

  if($t[$i] -match "####") {
      $start = $i
  }
  if($t[$i] -match "====-(\d+)") {
      $newval = $t[$start] -replace "####", $matches[1]
      $t[$start] = $newval
      $removeAt += $i
      $start = $i
  }

  $i += 1
}

foreach($idx in ($removeAt | Sort-Object -Descending)) {
    $t.removeAt($idx)
}

$t

Outputs

A;1;1;1234;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
A;1;1;5678;19/01/2015;08:45:58;UNKNOWN;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;
B;0;0;0;319.95;
B;0;0;0;319.89;

This does assume your file is consistent and that ====- always follows #### and the two are balanced. Extra logic is otherwise required to account for that.

Upvotes: 2

Related Questions