Reputation: 19
I am trying to change the domains of emails inside a text file for example "[email protected] to [email protected]". The emails are stored in a array and I am currently using a for loop with the replace method but I cannot get it to work. Here is the code that I have so far.
$folders = @('Folder1','Folder2','Folder3','Folder4','Folder5')
$names = @('John','Mary','Luis','Gary', 'Gil')
$emails = @("[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]")
$emails2 = @("[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]")
$content = "C:\Users\john\Desktop\contact.txt"
#create 10 new local users
foreach ($user in $users){ New-LocalUser -Name $user -Description "This is a test account." -NoPassword }
#Create 5 folders on desktop
$folders.foreach({New-Item -Path "C:\Users\John\Desktop\$_" -ItemType directory})
#create 5 folders on in documents
$folders.foreach({New-Item -Path "C:\users\john\Documents\$_" -ItemType directory})
#create contact.tct
New-Item -Path "C:\Users\John\Desktop" -Name "contact.txt"
#add 5 names to file
ForEach($name in $names){$name | Add-Content -Path "C:\Users\John\Desktop\contact.txt"}
#add 5 emails to file
ForEach($email in $emails){$email | Add-Content -Path "C:\Users\John\Desktop\contact.txt"}
#change emails to @comapny.com
for($i = 0; $i -lt 5; $i++){$emails -replace "$emails[$i]", $emails2[$i]}
Upvotes: 0
Views: 214
Reputation: 25041
In your particular example, you want to replace one string with another in each of your array elements. You can do that without looping:
$emails = $emails -replace '@domain\.com$','@company.com'
Since -replace
uses regex matching, the .
metacharacter must be escaped to be matched literally. In your case it probably does not matter since .
matches any character, but for completeness, you should escape it.
Using the .NET Regex class method Escape()
, you can programmatically escape metacharacters.
$emails -replace [regex]::Escape('@domain.com'),'@company.com'
With your code, in order to update $emails
, you need to interpolate your array strings properly and update your variable on each loop iteration:
for($i = 0; $i -lt 5; $i++) {
$emails = $emails -replace $emails[$i], $emails2[$i]
}
$emails # displays the updates
If $emails
contains other regex metacharacters besides just the single .
, it could be another reason why you are having matching issues. It would then just be easiest to escape the metacharacters:
for($i = 0; $i -lt 5; $i++) {
$emails = $emails -replace [regex]::Escape($emails[$i]), $emails2[$i]
}
$emails # displays the updates
Explanation:
When double quotes are parsed (if not inside a verbatim string), the parser will do string expansion. When this happens to variables references that include operators, only the variables are expanded and the rest of the quoted expression including the operator characters is treated as a verbatim string. You can see this with a trivial example:
$str = 'my string 1','my string 2'
"$str[0]"
Output:
my string 1 my string 2[0]
To get around this behavior, you either need to not use quotes around the expression or use the sub-expression operator $()
:
$str[0]
"$($str[0])"
Note that a quoted array reference will convert the array into a string. Each element of that array will be separated based on the $OFS
value (single space by default) of your environment.
Upvotes: 3