好的,所以你真的应该更新你的问题而不是在评论中发布代码,因为它真的很难阅读。这就是我认为你的意图:
$file = 'D:\sources\scripts\2.txt'
$content = Get-Content $file | foreach ($line in $content) {
if ($line.Contains('CN=')) {
$variable = $line.Split(',').Split('=')[2]
$variable1 = $variable -replace $variable, "Compagny"
} Set-Content -path $file
}
这肯定有一些语法错误。第一行很棒,您定义了路径。然后事情就出错了......您对Get-Content 的调用很好,它将获取文件的内容,并将它们发送到管道中。
您将它直接导入ForEach 循环,但它是错误的类型。你真正想要的是一个ForEach-Object 循环(这可能会令人困惑,因为在这样的管道中使用它时可以缩短为ForEach)。 ForEach-Object 循环不声明内部变量(例如($line in $content)),而是脚本块使用自动变量$_。所以你的循环需要变成这样:
Get-Content $file | ForEach { <do stuff> } | Set-Content
接下来让我们看看这个循环的内部。您使用If 语句来查看该行是否包含“CN=”、可理解和功能。如果是这样,则将行拆分为逗号,然后再次拆分为等号,选择第二条记录。嗯,您在拆分一个字符串的任何时候都会创建一个字符串数组,并且您已经拆分了两次字符串,但只指定要在第二次拆分时使用该数组的哪个记录。那可能是个问题。无论如何,您将该子字符串分配给$variable,然后将整个内容替换为“公司”并将该输出存储到$variable1。所以这里有几个问题。在逗号上拆分字符串后,您将拥有以下字符串数组:
"LDAP Location = **CN=EANG04W**"
"OU=EANG"
"DC=afp"
"DC=local"
这是一个包含 4 个字符串对象的数组。因此,您尝试在等号上至少拆分其中一个(因为您没有指定哪一个)。您现在有一个包含 4 个数组对象的数组,其中每个对象都有 2 个字符串对象:
("LDAP Location", "**CN", "EANG04W**")
("OU", "EANG")
("DC","afp")
("DC","local")
此时您确实指定了第三条记录(PowerShell 中的数组从记录 0 开始,因此 [2] 指定了第三条记录)。但是您没有指定第一个数组中的哪条记录,所以它只会抛出错误。假设您实际上选择了您真正想要的东西,我猜那将是“EANG04W”。 (顺便说一句,那将是$_.Split(",")[0].Split("=")[1])。然后将其分配给$Variable,并继续将其全部替换为“公司”,因此在 PowerShell 扩展变量后,它会如下所示:
$variable1 = "EANG04W" -replace "EANG04W", "company"
好的,您刚刚成功地将“公司”分配给了一个变量。你的 If 语句到此结束。您永远不会从 If 语句中输出任何内容,因此 Set-Content 无需设置任何内容。此外,它会为通过管道传输到 ForEach 语句的每一行设置任何内容,每次都重新编写文件,但幸运的是,该脚本不起作用,因此它没有删除您的文件。另外,由于您试图通过管道传输到 Set-Content,因此管道末端没有输出,因此您绝对没有为 $content 分配任何内容。
那么让我们尝试修复它,好吗?第一行?效果很好!不用找了。现在,我们没有在变量中保存任何内容,我们只是想更新文件的内容,所以不需要$Content =。那我们就继续前进,好吗?我们将Get-Content 通过管道传输到ForEach 循环中,就像您尝试做的那样。一旦进入ForEach 循环,我们将做一些不同的事情。 -replace 方法执行 RegEx 匹配。我们可以在这里利用它来发挥我们的优势。我们将为每一行替换您感兴趣的文本,如果找不到,则不会进行替换,并将每一行传递到管道中。 ForEach 的内部看起来像这样:
$_ -replace "(<=CN\=).*?(?=,)", "Company"
可以在此处查看该 RegEx 匹配的细分:https://regex101.com/r/gH6hP2/1
但是,假设它会查找紧接在其前面有“CN=”的文本,并一直到它后面的第一个逗号。在您的示例中,这包括两个尾随星号,但不触及前导星号。那是你的意图吗?这将使您的示例文件的最后一行:
Primary Owner = **CN=Company,OU=EANG,DC=afp,DC=localenter code here
好吧,如果这符合预期,那么我们就有了赢家。现在我们关闭ForEach 循环,并将输出通过管道传输到Set-Content,一切就绪!就个人而言,我强烈建议输出到一个新文件,以防您以后由于某种原因需要引用原始文件,所以这就是我要做的。
$file = 'D:\sources\scripts\2.txt'
$newfile = Join-Path (split-path $file) -ChildPath ('Updated-'+(split-path $file -Leaf))
Get-Content $file | ForEach{$_ -replace "(?<=CN\=).*?(?=,)", "Company"} | Set-Content $newfile
好的,就是这样。该代码将生成具有以下内容的 D:\sources\scripts\Updated-2.txt:
Computer Location = afp.local/EANG
Description = RED_TXT
Device Name = EANG04W
Domain Name = afp.local
Full Name = Admintech
Hardware Monitoring Type = ASIC2
Last Blocked Application Scan Date = 1420558125
Last Custom Definition Scan Date = 1348087114
Last Hardware Scan Date = 1420533869
Last Policy Sync Date = 1420533623
Last Software Scan Date = 1420533924
Last Update Scan Date = 1420558125
Last Vulnerability Scan Date = 1420558125
LDAP Location = **CN=Company,OU=EANG,DC=afp,DC=local
Login Name = ADMINTECH
Main Board OEM Name = Dell Inc.
Number of Files = 384091
Primary Owner = **CN=Company,OU=EANG,DC=afp,DC=localenter code here