2

I have multiple text documents, each with multiple lines of information, and I'm trying to replace a single line of text within each document with text of my choosing. The single line of text that is to be replaced does not have a consistent length or set of characters across the multiple documents. Also, the placement of this line of text is not always located at the same place within the document. The only consistent factor here is the string directly above the line of text to be replaced is the same string across all documents - "Courier". I'm trying to use the word "Courier" as my reference point with which I'd replace the subsequent line of text with something of my choosing.

Any help would be greatly appreciated! Thanks in advance!

Below I have included the script that I've created so far; however, I am reaching the limits of my capability to complete this. Currently, the script executes successfully without errors, but the line I'm trying to replace does not get replaced - Instead, the text I'm looking to input as the replacement is entered below "Courier" and the text I don't need (that I'd like to be replaced) is moved down the document, now located directly under the new text I've entered in my script. Here's an example of what I get when I run my script in its current state:

Courier
Entry location 153
Sidewalk0156378

In this case, "Sidewalk0156378" is the old text that used to be directly under "Courier" before the script was ran, and it needs to be replaced. "Entry location 153" is the new text that should be taking the place of "Sidewalk0156378".

$path = "C:\temp"
if(!(Test-Path $path)){
    New-Item -ItemType Directory -Force -Path $path
}

$currentCourier = "C:\Temp\currentCourier.txt"
$editCourier = "C:\Temp\editCourier.txt"
$newCourier = "C:\Temp\newCourier.txt"


Get-Content $currentCourier | ForEach-Object {
    $_
    if ($_ -match 'Courier') {
        "Entry location"
    }
} | Set-Content $editCourier


$oldEntry = Get-Content $editCourier
$rem = @()
@("Courier") | ForEach-Object {
  $rem += $oldEntry[(($oldEntry | Select-String -Pattern "$_").LineNumber)..(($oldEntry | Select-String -Pattern "$_").LineNumber+1)]
}
Compare-Object $oldEntry $rem | Select-Object -ExpandProperty InputObject | Set-Content $newEntry

4
  • looks like more than replacing you're actually looking to insert a new line after Courier right? Commented Jan 31, 2023 at 3:44
  • There is already a line there before I run my script - in my example "Sidewalk0156378" - But I want "Sidewalk0156378" to go away and be replaced by a string of my choosing. Commented Jan 31, 2023 at 3:46
  • I removed the tags from the title and post for a reason. The tagging system works extremely well here and doesn't need help. Repeating it in the title or body is redundant noise. Please DO NOT put them back in. Commented Jan 31, 2023 at 3:46
  • Apologies, Ken. I'll make sure to leave them out going forward. Commented Jan 31, 2023 at 4:43

1 Answer 1

2

The following uses a switch to process the file line by line in combination with the -Wildcard parameter to match any line having the key word.

& {
    $skipNext = $false
    switch -Wildcard -File $currentCourier {
        # if line contains Courier
        '*Courier*' {
            # output this line
            $_
            # set this variable to skip next line
            $skipNext = $true
            # output new value that replaces next line
            'new value here'
            # skip next conditions
            continue
        }
        # if the bool was set in previous iteration
        { $skipNext } {
            # set it to false again
            $skipNext = $false
            # and go next
            continue
        }
        # else, output line as is
        Default { $_ }
    }
} | Set-Content $newCourier

Using the logic above with a hardcoded example:

$content = '
line 1
line 2
line 3 has Courier
line 4 should be replaced
line 5
' -split '\r?\n'

$skipNext = $false
switch -Wildcard ($content) {
    '*Courier*' {
        $_
        $skipNext = $true
        'Entry location 153'
        continue
    }
    { $skipNext } {
        $skipNext = $false
        continue
    }
    Default { $_ }
}

Output to the console would become:

line 1
line 2
line 3 has Courier
Entry location 153
line 5
Sign up to request clarification or add additional context in comments.

9 Comments

Thanks, Santiago! I'll give this a try and get back to you.
@KoreyMendes btw, this will replace all next lines after the keyword, if the keyword only exist 1 time in the file it should be fine, if there can be more appearances of the keyword and you only need to replace the first one there should be added a new condition for this
In my instance, the word Courier only appears once in each file, so I think I should be fine running this as is. Thanks for the heads up though!
This line $null = $switch.MoveNext() is throwing an error because it's calling a method on a null-valued expression. What should $switch be defined as in your example? @santiago
No problem, @Santiago. I ses you updated your original post. I will try the new code shortly. Thanks again!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.