试图替换文件中的字符串但替换太多
Trying to replace strings in a file but its replacing too much
我正在尝试通过 txt 日志文件将 PowerShell 脚本组合到 运行 并删除域名/url。
到目前为止,我只是对文件进行查找替换,但是当我尝试这样做时,它并没有像我期望的那样工作,例如
如果我有一个包含以下内容的文本文件:
intranet.contoso.com and some text
在我的脚本 运行 将 intranet.contoso.com 替换为 DOMAIN1 之后,我得到的输出是
DOMAIN1 DOMAIN1aDOMAIN1nDOMAIN1dDOMAIN1 DOMAIN1sDOMAIN1oDOMAIN1mDOMAIN1eDOMAIN1 DOMAIN1tDOMAIN1eDOMAIN1xDOMAIN1tDOMAIN1
所以我不确定我哪里出错了。到目前为止我的代码是
$domains = ,("mydomain.net","mydomain"),("yourdomain.net","yourdomain"),("mydomain2.net","mydomain2")
$path = Read-Host "Please enter the full path to the directory containing the files to be sanatized"
$files = Get-ChildItem –Path $path *.txt
foreach ($file in $files)
{
for($x=0; $x -lt $domains.Count; $x++)
{
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace $domains[$x][0], "DOMAIN$($x+1)" } |
Set-Content $file.PSPath
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace $domains[$x][1], "DOMAIN$($x+1)" } |
Set-Content $file.PSPath
}
}
正如其他两个答案所指出的那样,数组的数组与 ,(x,y,),(foo,bar)" syntax. Use of
@` 混淆了,或者只是删除了前导逗号就可以解决这个问题。
我还发现写入与您正在读取的文件相同的文件对我来说效果不佳,即使使用 (Get-Content $file.PSPath)
语法也是如此。通过写入新文件然后重命名,我获得了更一致的结果。
我认为您遇到的问题是您创建多维数组的方式。当我使用你的线路时,我得到了一些非常不同的东西。
尝试将第一行重写为(数组的数组):
$domains = @(@("mydomain.net","mydomain"),@("yourdomain.net","yourdomain"),@("mydomain2.net","mydomain2"))
我确定您的主要问题是在定义 $domains
时使用了 unary operator。如果你看看你的第一个元素。
PS D:\temp> $domains[0]
mydomain.net
mydomain
如您所料,但这是问题发生的下一步。让我们尝试获取 "mydomain" 字符串
PS D:\temp> $domains[0][1]
什么都没有?这很奇怪。不,如果你知道发生了什么,就不会真的。让我们看看这个锯齿状数组的另一个元素。
PS D:\temp> $domains[0][0]
mydomain.net
mydomain
这是什么鬼话?数组第一个元素的第一个元素是另一个数组。现在看这个:
PS D:\temp> $domains[0][0][1]
mydomain
有几个步骤前我们试图获取的元素。您创建了一个数组,其中第一个元素是一个包含两个元素的数组。
你的测试文件看起来像它那样的原因是第一个例子会尝试使用 $domains[0][1]
这将是 null 并匹配字符之间的每个 space 因此你的输出。
简单删除一元运算符。
$domains = ("mydomain.net","mydomain"),("yourdomain.net","yourdomain"),("mydomain2.net","mydomain2")
还值得注意的是 -replace
是一个正则表达式运算符,因此您需要小心地在匹配字符串中使用元字符。例如期间。静态正则表达式方法 escape 可以为您解决这个问题,以确保您的字符串按字面匹配。
$_ -replace [regex]::Escape($domains[$x][1]), "DOMAIN$($x+1)"
知道 -replace
也是一个数组运算符,您还可以改进替换逻辑。所以在你的循环中你可以替换这个
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace $domains[$x][0], "DOMAIN$($x+1)" } |
Set-Content $file.PSPath
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace $domains[$x][1], "DOMAIN$($x+1)" } |
Set-Content $file.PSPath
有了这个。
(Get-Content $file) -replace $domains[$x][0], "DOMAIN$($x+1)" -replace $domains[$x][1], "DOMAIN$($x+1)" |
Set-Content $file
.pspath
while valid 不是必需的。 cmdlet Get/Set-Content
将根据 $file
对象中的参数名称匹配路径。我真的帮不上什么忙。这是未经测试的,因为我没有方便的示例文本文件。测试并测试更多以确保。
我正在尝试通过 txt 日志文件将 PowerShell 脚本组合到 运行 并删除域名/url。
到目前为止,我只是对文件进行查找替换,但是当我尝试这样做时,它并没有像我期望的那样工作,例如
如果我有一个包含以下内容的文本文件:
intranet.contoso.com and some text
在我的脚本 运行 将 intranet.contoso.com 替换为 DOMAIN1 之后,我得到的输出是
DOMAIN1 DOMAIN1aDOMAIN1nDOMAIN1dDOMAIN1 DOMAIN1sDOMAIN1oDOMAIN1mDOMAIN1eDOMAIN1 DOMAIN1tDOMAIN1eDOMAIN1xDOMAIN1tDOMAIN1
所以我不确定我哪里出错了。到目前为止我的代码是
$domains = ,("mydomain.net","mydomain"),("yourdomain.net","yourdomain"),("mydomain2.net","mydomain2")
$path = Read-Host "Please enter the full path to the directory containing the files to be sanatized"
$files = Get-ChildItem –Path $path *.txt
foreach ($file in $files)
{
for($x=0; $x -lt $domains.Count; $x++)
{
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace $domains[$x][0], "DOMAIN$($x+1)" } |
Set-Content $file.PSPath
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace $domains[$x][1], "DOMAIN$($x+1)" } |
Set-Content $file.PSPath
}
}
正如其他两个答案所指出的那样,数组的数组与 ,(x,y,),(foo,bar)" syntax. Use of
@` 混淆了,或者只是删除了前导逗号就可以解决这个问题。
我还发现写入与您正在读取的文件相同的文件对我来说效果不佳,即使使用 (Get-Content $file.PSPath)
语法也是如此。通过写入新文件然后重命名,我获得了更一致的结果。
我认为您遇到的问题是您创建多维数组的方式。当我使用你的线路时,我得到了一些非常不同的东西。
尝试将第一行重写为(数组的数组):
$domains = @(@("mydomain.net","mydomain"),@("yourdomain.net","yourdomain"),@("mydomain2.net","mydomain2"))
我确定您的主要问题是在定义 $domains
时使用了 unary operator。如果你看看你的第一个元素。
PS D:\temp> $domains[0]
mydomain.net
mydomain
如您所料,但这是问题发生的下一步。让我们尝试获取 "mydomain" 字符串
PS D:\temp> $domains[0][1]
什么都没有?这很奇怪。不,如果你知道发生了什么,就不会真的。让我们看看这个锯齿状数组的另一个元素。
PS D:\temp> $domains[0][0]
mydomain.net
mydomain
这是什么鬼话?数组第一个元素的第一个元素是另一个数组。现在看这个:
PS D:\temp> $domains[0][0][1]
mydomain
有几个步骤前我们试图获取的元素。您创建了一个数组,其中第一个元素是一个包含两个元素的数组。
你的测试文件看起来像它那样的原因是第一个例子会尝试使用 $domains[0][1]
这将是 null 并匹配字符之间的每个 space 因此你的输出。
简单删除一元运算符。
$domains = ("mydomain.net","mydomain"),("yourdomain.net","yourdomain"),("mydomain2.net","mydomain2")
还值得注意的是 -replace
是一个正则表达式运算符,因此您需要小心地在匹配字符串中使用元字符。例如期间。静态正则表达式方法 escape 可以为您解决这个问题,以确保您的字符串按字面匹配。
$_ -replace [regex]::Escape($domains[$x][1]), "DOMAIN$($x+1)"
知道 -replace
也是一个数组运算符,您还可以改进替换逻辑。所以在你的循环中你可以替换这个
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace $domains[$x][0], "DOMAIN$($x+1)" } |
Set-Content $file.PSPath
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace $domains[$x][1], "DOMAIN$($x+1)" } |
Set-Content $file.PSPath
有了这个。
(Get-Content $file) -replace $domains[$x][0], "DOMAIN$($x+1)" -replace $domains[$x][1], "DOMAIN$($x+1)" |
Set-Content $file
.pspath
while valid 不是必需的。 cmdlet Get/Set-Content
将根据 $file
对象中的参数名称匹配路径。我真的帮不上什么忙。这是未经测试的,因为我没有方便的示例文本文件。测试并测试更多以确保。