好的,所以你真的應該更新你的問題了,沒有在評論中發佈代碼,因爲它很難閱讀。以下是我認爲你的意圖:
$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語句的每一行設置任何內容,每次都重寫該文件,但幸運的是,腳本無法正常工作,因此它不會擦除您的文件。此外,由於您正嘗試管道到設置內容,在管道末端沒有輸出,因此您完全沒有分配給$content
。
那麼讓我們嘗試修復它吧?第一行?很棒!不用找了。現在,我們沒有在變量中保存任何內容,我們只是想更新文件的內容,因此不需要在那裏有$Content =
。我們會繼續前進,我們會嗎?我們將Get-Content
變成ForEach
循環,就像你試圖做的一樣。一旦進入ForEach
循環,我們會做一些有點不同的事情。 -replace
方法執行RegEx匹配。我們可以在這裏利用這個優勢。我們將替換您感興趣的每一行的文本,如果沒有找到,則不會進行替換,並將每行傳遞到管道中。這將是這個樣子的ForEach
內部:
$_ -replace "(<=CN\=).*?(?=,)", "Company"
該正則表達式匹配的故障可以在這裏看到: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
是否要將更改後的文本保存到新文件中? – user2963623
那麼問題是什麼?讀文件?更改內容?保存輸出?添加腳本並解釋什麼是令人頭疼的部分。 – vonPryz
我試過這段代碼:$ 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 }但它似乎語法不正確!謝謝(我需要將更改的文本保存到同一個文件) – salakta