简体   繁体   中英

Needing a part of a string, as a variable

Apologies if my terminology is not on part with PowerShell and...the rest. I am not a developer by trade so I am not to clued up with what is possible.

My scenario:

I have thousands of files in a folder, and each of them carries the same string: (this is an xml file but I hope for now irrelevant.)

<TxId>0003/2021-04-09/000625514690</TxId>

Below is PowerShell code that changes the 000625514690 part to something random (between min and max of course)

#Set your path here, on the first folder.
$path = "C:\Users\Dell\Downloads\FNB 1 Trans\File Creation\DDINP"

#Get the list of all *.txt, with recursivity
$list = Get-ChildItem $path -Recurse -Include "*.xml"

#Replace the elements
$initialvar=  '000625514690'
$newvar = $null

foreach($item in $list)
{
#you get a random value between 111111 and 2222222 
$newvar = Get-Random -Minimum 111111111 -Maximum 999999999
                              
#here in each file, you replace the initial value(000625514690) with the new value
(Get-Content $item) -replace $initialvar,$newvar | Set-Content $item
}

Now this works great for me. But in the string <TxId>0003/2021-04-09/000625514690</TxId> how can I set only the 000 as the variable? Of course I can't just put 000 in there as 000 comes along a lot of the times in the file.

OR

If the 000625514690 value is not static through all the files(but it will always have 3 "0"s in the front), how would I then tell PowerShell to ignore the digits behind the 000 in the <TxId>0003/2021-04-09/000625514690</TxId> string and just change the zeros?

You guys are awesome with your brains and I appreciate. ===================================================================Part 2

Sorry for posting like this -

  1. your code worked 100% - thank you
$path = "C:\Users\Dell\Downloads\FNB 1 Trans\File Creation\DDINP"
$list = Get-ChildItem $path -Recurse -Include "*.xml"
$initialvar=  '000625514690'
$newvar = $null

foreach($item in $list)
{
 (Get-Content -Raw $item) -replace '(?<=/)000(?=\d)',(Get-Random -Minimum 111 -Maximum 999) |Set-Content -NoNewLine $item
}

Is what I ended with.

2.

But, may I ask, II want the 000 to be sequential rather than Get-Random how would that look like?

$path = "C:\Users\Dell\Downloads\FNB 1 Trans\File Creation\DDINP"
$list = Get-ChildItem $path -Recurse -Include "*.xml"
$initialvar=  '000625514690'
$newvar = $null


foreach($item in $list)
    {
        
        #for(($i = 1); $i -le 999; $i++)
        for ($i = 0; $i -le 999; $i++)
        {
        (Get-Content -Raw $item) -replace '(?<=/)000(?=\d)',('00'+$i) |Set-Content -NoNewLine $item
        }
    }

I have been trying the above on my own and although it replaces the values, without the ',('00'+$i) it then takes the ID and makes it <TxId>0003/2021-04-09/1625514690</TxId> . The length of this field must stay 28. I added the '00' but that will also become an issue after 9 as it will be 0010, make the field 29characters.

Also what the above code does, it doesn't increment the values in the file nor the files in the folder, so they all are 001 - and I really tried my best moving the code around to see what makes a change.

Really sorry for adding onto my question, but I found out that this is an Input folder, and the "random" values of part one must correlate with an output file.

Instead of trying to use the random way, copy from these and paste it somehow with magic code into the output files, I'd let it all be sequential and run it over all those files...

I'm pretty noob with RegEx and there is most likely a better way to do this but see if this works for you:

PS /~> '<TxId>0003/2021-04-09/000625514690</TxId>' -replace '(000)([0-9]{9})',('{0}$2' -f (Get-Random -Minimum 111 -Maximum 999))
<TxId>0003/2021-04-09/712625514690</TxId>

PS /~> '<TxId>0003/2021-04-09/000625514690</TxId>' -replace '(000)([0-9]{9})',('{0}$2' -f (Get-Random -Minimum 111 -Maximum 999))
<TxId>0003/2021-04-09/497625514690</TxId>

PS /~> '<TxId>0003/2021-04-09/000625514690</TxId>' -replace '(000)([0-9]{9})',('{0}$2' -f (Get-Random -Minimum 111 -Maximum 999))
<TxId>0003/2021-04-09/664625514690</TxId>

I hope someone can help me explain this better but basically this regex captures 3 groups:

PS /~> $Matches

Name                           Value                                                                                        
----                           -----                                                                                        
2                              625514690                                                                                    
1                              000                                                                                          
0                              000625514690  
  • $0 is the whole match (we are not interested in this one)
  • $1 this group is the one we wanna replace
  • $2 this is the group we wanna leave intact

If it's sufficient to identify what you want to replace as follows:

  • 3 zeros ( 000 ), if :

    • preceded by /
    • and followed by a digit .

you can use the following approach, which combines the regex-based -replace operator with positive lookbehind/ahead assertions ( (?<=...) and (?=...) ):

(Get-Content $item) -replace '(?<=/)000(?=\d)', 
                             (Get-Random -Minimum 111 -Maximum 999) |
  Set-Content $item

You can speed up the operation by processing the input file as a whole , using Get-Content -Raw , which then requires passing -NoNewLine to Set-Content to prevent an additional trailing newline:

(Get-Content -Raw $item) -replace '(?<=/)000(?=\d)', 
                                  (Get-Random -Minimum 111 -Maximum 999) |
  Set-Content -NoNewLine $item

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM