Home > database >  Using Powershell to copy and replace content from one file to another
Using Powershell to copy and replace content from one file to another

Time:03-01

I have two files: FileA and FileB, they are nearly identical.

Both files have a section which starts with ////////// MAIN \\\\\\\\\\. I need to replace the whole content from this point until the end of the file.

So the process high level looks like:

  1. find content (starting with ////////// MAIN \\\\\\\\\\) until the end of the file in FileA and copy it to clipboard
  2. find content (starting with ////////// MAIN \\\\\\\\\\) until the end of the file in FileB and replace it with the content from the clipboard

How do I do this?

I understand that it would look like this (found it online) but I'm missing the pattern and logic I can use for selecting the text until the end of the file:

# FileA
$inputFileA = "C:\fileA.txt"
# Text to be inserted
$inputFileB = "C:\fileB.txt"
# Output file
$outputFile = "C:\fileC.txt"
# Find where the last </location> tag is
if ((Select-String -Pattern "\</location\>" -Path $inputFileA |
    select -last 1) -match ":(\d ):")
{
    $insertPoint = $Matches[1]
    # Build up the output from the various parts
    Get-Content -Path $inputFileA | select -First $insertPoint | Out-File $outputFile
    Get-Content -Path $inputFileB | Out-File $outputFile -Append
    Get-Content -Path $inputFileA | select -Skip $insertPoint | Out-File $outputFile -Append
}

CodePudding user response:

You could do that in two lines of code:

# first write the top part including the '////////// MAIN \\\\\\\\\\' from FileB to the new file
((Get-Content -Path "D:\Test\fileB.txt" -Raw) -split '(?<=/  MAIN \\ \r?\n)', 2)[0]  | Set-Content -Path "D:\Test\fileC.txt" -NoNewline
# then append the bottom part excluding the '////////// MAIN \\\\\\\\\\' from FileA to the new file
((Get-Content -Path "D:\Test\fileA.txt" -Raw) -split '/  MAIN \\ \r?\n', 2)[-1]      | Add-Content -Path "D:\Test\fileC.txt"

Regex details:

(?<=         # Assert that the regex below can be matched, with the match ending at this position (positive lookbehind)
   /         # Match the character “/” literally
             # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   \ MAIN\   # Match the characters “ MAIN ” literally
   \\        # Match the character “\” literally
             # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   \r        # Match a carriage return character
      ?      # Between zero and one times, as many times as possible, giving back as needed (greedy)
   \n        # Match a line feed character
)

Or, if the files are quite large:

# first write the top part including the '////////// MAIN \\\\\\\\\\' from FileB to the new file
$copyThis = $true
$content = switch -Regex -File "D:\Test\fileB.txt" {
    '/  MAIN \\ '  { $copyThis = $false; $_ ; break}
    default { if ($copyThis) { $_ } }
}
$content | Set-Content -Path "D:\Test\fileC.txt"

# then append the bottom part excluding the '////////// MAIN \\\\\\\\\\' from FileA to the new file
$copyThis = $false
$content = switch -Regex -File "D:\Test\fileA.txt" {
    '/  MAIN \\ '  { $copyThis = $true }
    default { if ($copyThis) { $_ } }
}
$content | Add-Content -Path "D:\Test\fileC.txt" 
  • Related