Replace characters with incrementing value

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Replace characters with incrementing value



I'm trying to figure out how to replace a certain string that repeats itself multiple time in a txt file with an incrementing value.



What I try to achieve is the following:



I have multiple HTML links in a table, each of the links have the exact same ending i.e.: XYZ



I want to change XYZ to 1, 2, 3, 4, 5 and so on... using PowerShell.


(Get-Content c:temptest.txt).replace('XYZ', 'MyValue') |
Set-Content c:temptest.txt



It is the 'MyValue' part of using an incrementing number for each replacement I'm not sure how to achieve it.




2 Answers
2



Hint: be aware of using Get-Content | .... | Set-Content to the same file due to possible data loss! It doesn't apply to reading file in a subexpression/grouping expression as you did, but be aware of it in the future (as a best practice). Credits to @Ansgar Wiechers for clarification.


Get-Content | .... | Set-Content



Solution:



You can define callback function to [Regex]::Replace (String, String, MatchEvaluator) method:


[Regex]::Replace (String, String, MatchEvaluator)


$global:counter = 0
$content = (Get-Content c:temptest.txt)

# Below can be used to verify it's working correctly instead of creating a file
# $content = "aXYZ","bXYZ","cXYZ","dXYZ","eXYZ"

$content | % [Regex]::Replace($_, 'XYZ', return $global:counter += 1) | Set-Content c:temptest.txt



Output will be:


a1
b2
c3
d4
e5



Explanation:



The parameters you pass to Replace are as follows:


Replace



The custom method increments the counter each time the regex is matched. Unfortunately, for some reason, it requires you to use global variable scope which is in general not the best practice if not needed (as mentioned by @Paxz in the comments).



As @TessellatingHeckler found out, the first version of solution used Replace on $content variable which resulted in removing all newlines. You have to use Foreach-Object (or % as its alias) to do the replacing in each single line.


Replace


$content


Foreach-Object


%





The same can be achieved without the global scope. Using a global scope, where it is not explicit needed is a bad practice.
– Paxz
Aug 6 at 13:32


global





Yeah I tested it wrong, seems like i really needs another scope (that kinda makes me sad...).
– Paxz
Aug 6 at 13:44





Incorrect output, you've implicitly joined all the lines with a space into one string. Now the file has no newlines.
– TessellatingHeckler
Aug 6 at 14:15





You're welcome! Please remember to mark the answer which helped you as accepted (see What should I do when someone answers my question?.
– robdy
Aug 6 at 14:46






Writing to the same file is not an issue if you read the file in a subexpression/grouping expression as the OP does.
– Ansgar Wiechers
Aug 6 at 14:50



Same as @robdy answer, but without the global scope refference:


global


# Simulation of Get-Content
$content = "aXYZ","bXYZ","cXYZ","dXYZ","eXYZ"

$i = 0
$result = $content.ForEach(
$i++
$_ -replace 'XYZ', $i
)

$result | Out-File -FilePath "$env:TEMPtest.txt" -Encoding utf8 -NoClobber



We're basically looping over the content of the file and replace the string XYZ with the number. Then we save that in to a new variable, which is later used to write the new content to the file.


XYZ





This will only work if there is one match per line
– TessellatingHeckler
Aug 6 at 14:13






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard