![](/img/trans.png)
[英]Powershell replace special characters string in all files in directory path
[英]PowerShell: Replace string in all .txt files within directory
我正在嘗試替換目錄中字符串的每個實例。 但是我的代碼沒有替換任何東西。
到目前為止我所擁有的:
測試文件夾包含多個文件和文件夾,其中包含我需要更改的內容。 文件夾包含 .txt 文檔,.txt 文檔包含如下字符串: Content reference="../../../PartOfPath/EN/EndofPath/Caution.txt" 我需要更改為: Content reference= “../../../PartOfPath/FR/EndofPath/Caution.txt”
在提出這個問題之前,是的,必須以這種方式完成,因為還有其他類似的字符串我不想編輯。 所以我不能只用 FR 替換 EN 的所有實例。
$DirectoryPath = "C:\TestFolder"
$Parts =@(
@{PartOne="/PartOfPath";PartTwo="EndofPath/Caution.txt"},
@{PartOne="/OtherPartOfPath";PartTwo="EndofPath/Note.txt"},
@{PartOne="/ThirdPartOfPath";PartTwo="OtherEndofPath/Warning.txt"}) | % { New-Object object | Add-Member -NotePropertyMembers $_ -PassThru }
Get-ChildItem $DirectoryPath | ForEach {
foreach($n in $Parts){
[string]$PartOne = $n.PartOne
[string]$PartTwo = $n.PartTwo
$ReplaceThis = "$PartOne/EN/$PartTwo"
$WithThis = "$PartOne/FR/$PartTwo"
(Get-Content $_) | ForEach {$_ -Replace $ReplaceThis, $WithThis} | Set-Content $_
}
}
代碼將運行並覆蓋文件,但不會進行任何編輯。
在進行故障排除時,我遇到了這個潛在的原因:
該測試有效:
$FilePath = "C:\TestFolder\Test.txt"
$ReplaceThis ="/PartOfPath/EN/Notes/Note.txt"
$WithThis = "/PartOfPath/FR/Notes/Note.txt"
(Get-Content -Path $FilePath) -replace $ReplaceThis, $WithThis | Set-Content $FilePath
但是這個測試沒有
$FilePath = "C:\TestFolder\Test.txt"
foreach($n in $Parts){
[string]$PartOne = $n.PartOne
[string]$PartTwo = $n.PartTwo
[string]$ReplaceThis = "$PartOne/EN/$PartTwo"
[string]$WithThis = "$PartOne/FR/$PartTwo"
(Get-Content -Path $FilePath) -replace $ReplaceThis, $WithThis | Set-Content $FilePath
}
如果您能幫助我了解這里出了什么問題,我將不勝感激。
感謝@TessellatingHeckler 的評論,我修改了我的代碼並找到了這個解決方案:
$DirectoryPath = "C:\TestFolder"
$Parts =@(
@{PartOne="/PartOfPath";PartTwo="EndofPath/Caution.txt"},
@{PartOne="/OtherPartOfPath";PartTwo="EndofPath/Note.txt"},
@{PartOne="/ThirdPartOfPath";PartTwo="OtherEndofPath/Warning.txt"}) | % { New-Object object | Add-Member -NotePropertyMembers $_ -PassThru }
Get-ChildItem $LanguageFolderPath -Filter "*.txt" -Recurse | ForEach {
foreach($n in $Parts){
[string]$PartOne = $n.PartOne
[string]$PartTwo = $n.PartTwo
$ReplaceThis = "$PartOne/EN/$PartTwo"
$WithThis = "$PartOne/FR/$PartTwo"
(Get-Content $_) | ForEach {$_.Replace($ReplaceThis, $WithThis)} | Set-Content $_
}
}
有2個問題:
1: -replace 沒有按我的預期工作,所以我不得不改用.replace
2:原來的 Get-ChildItem 沒有返回任何值,必須用上面的版本替換。
謝謝你的幫助。
默認情況下,PowerShell 的-replace
運算符是基於正則表達式且不區分大小寫的:
\
-轉義模式中的元字符或調用[regex]::Escape()
。 相比之下, [string]
類型的.Replace()
方法執行文字替換並且區分大小寫,始終在 Windows PowerShell 中,默認情況下在 PowerShell 中(有關更多信息,請參閱此答案7+)
所以:
正如TessellatingHeckler指出的那樣,鑒於您的搜索字符串似乎不包含需要 escaping 的正則表達式元字符(例如.
或\
),因此沒有明顯的原因說明您的原始方法不起作用。
Given that you're looking for literal substring replacements, the [string]
type's .Replace()
is generally the simpler and faster option if case-SENSITIVITY is desired / acceptable (invariably so in Windows PowerShell; as noted, in PowerShell (Core) 7+,您也可以選擇使.Replace()
不區分大小寫)。
但是,由於您需要執行多次替換,因此可以使用更簡潔的單遍-replace
解決方案(盡管必須測試它是否實際上執行得更好;如果您需要區分大小寫,請使用-creplace
代替-replace
):
$oldLang = 'EN'
$newLang = 'FR'
$regex = @(
"(?<prefix>/PartOfPath/)$oldLang(?<suffix>/EndofPath/Caution.txt)",
"(?<prefix>/OtherPartOfPath/)$oldLang(?<suffix>/EndofPath/Note.txt)",
"(?<prefix>/ThirdPartOfPath/)$oldLang(?<suffix>/OtherEndofPath/Warning.txt)"
) -join '|'
Get-ChildItem C:\TestFolder\Test.txt -Filter *.txt -Recurse | ForEach-Object {
($_ |Get-Content -Raw) -replace $regex, "`${prefix}$newLang`${suffix}" |
Set-Content -LiteralPath $_.FullName
}
請參閱此 regex101.com 頁面,了解正則表達式的說明以及對其進行試驗的能力。
用作替換操作數的表達式"`${prefix}$newLang`${suffix}"
混合了 PowerShell 的預先字符串插值( $newLang
,也可以寫為${newLang}
)和引用正則表達式中命名的捕獲組(例如(?<prefix>...)
),只是巧合地使用與 PowerShell 變量相同的符號(盡管需要將名稱括在{...}
中;另外,這里是$
字符。必須是`
-escaped 以防止 PowerShell 的字符串插值解釋它們); 有關背景信息,請參閱此答案。
請注意-Raw
與Get-Content
的使用,它將一個文本文件作為一個整體讀入 memory,作為單個多行字符串。 鑒於在這種情況下您不需要逐行處理,這大大加快了給定文件的處理速度。
作為一般提示:您可能需要將-Encoding
參數與Set-Content
一起使用以確保所需的字符編碼,因為 PowerShell 在讀取文件時從不保留文件的原始編碼。 By default, you'll get ANSI-encoded files in Windows PowerShell , and BOM-less UTF-8 files in PowerShell (Core) 7+ .
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.