0

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]}
1
  • Don't use quotes like "$emails[$i]" because that causes string expansion. Everything after the variable name starting with [ will just be appended to the string verbatim. Just use $emails[$i] instead. Since -replace doesn't actually update the stored array, you will need to update $emails on every iteration to keep your changes. Then output $emails outside of the loop at the end. Commented Jul 2, 2021 at 17:15

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

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.