Reputation: 83
I need to search and replace values in a file using the values from another file. For example, A.txt
has a string with a value LICENSE_KEY_LOC=test_lic
and B.txt
contains the string LICENSE_KEY_LOC=
or some value in it. Now I need to replace the complete string in B.txt
with the value from A.txt
. I tried the following but for some reason it does not work.
$filename = "C:\temp\A.txt"
Get-Content $filename | ForEach-Object {
$val = $_
$var = $_.Split("=")[0]
$var1 = Write-Host $var'='
$_ -replace "$var1", "$val"
} | Set-Content C:\temp\B.txt
Upvotes: 0
Views: 1654
Reputation: 25001
You may use the following, which assumes LICENSE_KEY_LOC=string is on a line by itself in the file and only exists once:
$filename = Get-Content "c:\temp\A.txt"
$replace = ($filename | Select-String -pattern "(?<=^LICENSE_KEY_LOC=).*$").matches.value
(Get-Content B.txt) -replace "(?<=^LICENSE_KEY_LOC=).*$","$replace" | Set-Content "c:\temp\B.txt"
For updating multiple single keys/fields in a file, you can use an array and loop through each element by updating the $Keys
array:
$filename = Get-Content "c:\temp\A.txt"
$Keys = @("LICENSE_KEY_LOC","DB_UName","DB_PASSWD")
ForEach ($Key in $Keys) {
$replace = ($filename | Select-String -pattern "(?<=^$Key=).*$").matches.value
(Get-Content "c:\temp\B.txt") -replace "(?<=^$Key=).*$","$replace" | Set-Content "c:\temp\B.txt"
}
You can put this into a function as well to make it more modular:
Function Update-Fields {
Param(
[Parameter(Mandatory=$true)]
[Alias("S")]
[ValidateScript({Test-Path $_})]
[string]$SourcePath,
[Parameter(Mandatory=$true)]
[Alias("D")]
[ValidateScript({Test-Path $_})]
[string]$DestinationPath,
[Parameter(Mandatory=$true)]
[string[]]$Fields
)
$filename = Get-Content $SourcePath
ForEach ($Key in $Fields) {
$replace = ($filename | Select-String -pattern "(?<=^$Key=).*$").matches.value
(Get-Content $DestinationPath) -replace "(?<=^$Key=).*$","$replace" | Set-Content $DestinationPath
}
}
Update-Fields -S c:\temp\a.txt -D c:\temp\b.txt -Fields "LICENSE_KEY_LOC","DB_UName","DB_PASSWD"
Explanation - Variables and Regex:
$replace
contains the result of a string selection that matches a regex pattern. This is a case-insensitive match, but you can make it case-sensitive using -CaseSensitive
parameter in the Select-String
command.(?<=^LICENSE_KEY_LOC=)
: Performs a positive lookbehind regex (non-capturing) of the string LICENSE_KEY_LOC=
at the beginning of a line.
(?<=)
is a positive lookbehind mechanism of regex^
marks the beginning of the string on each lineLICENSE_KEY_LOC=
is a string literal of the text.*$
: Matches all characters except newline and carriage return until the end of the string on each line
.*
matches zero or more characters except newline and carriage return because we did not specify single line mode.$
marks the end of the string on each line-replace "(?<=^LICENSE_KEY_LOC=).*$","$replace"
is the replace operator that does a regex match (first set of double quotes) and replaces the contents of that match with other strings or part of the regex capture (second set of double quotes).
"$replace"
becomes the value of the $replace
variable since we used double quotes. If we had used single quotes around the variable, then the replacement string would be literally $replace
.Get-Content "c:\temp\A.txt"
gets the contents of the file A.txt. It reads each line as a [string]
and stores each line in an [array]
object.Explanation - Function:
Parameters
$SourcePath
represents the path to the source file that you want to read. I added alias S
so that -S
switch could be used when running the command. It validates that the path exists ({Test-Path $_}
) before executing any changes to the files.
$DestinationPath
represents the path to the source file that you want to read. I added alias D
so that -D
switch could be used when running the command. It validates that the path exists ({Test-Path $_}
) before executing any changes to the files.
$Fields
is a string array. You can input a single string or multiple strings in an array format (@("string1","string2")
or "string1","string2"
). You can create a variable that contains the string array and then just use the variable as the parameter value like -Fields $MyArray
.
Upvotes: 2