[英]Replace string in all files of a folder with powershell
我剛剛開始使用Powershell,因為我需要制作一個腳本,將鏈接放在文件夾的所有文件(htm文件)中。 這些鏈接實際上鏈接了它們之間的所有文件。 我有一個文件夾中文件的列表(此文件稱為list.txt
,其中包含不帶擴展名的文件的名稱)
我想在每個文件中進行以下更改:
從:
<tspan x="53" y="54.8">Surveillance_Err_PRG</tspan>
至:
<tspan x="53" y="54.8"><a href="C:/[...path...]/HTMs/Surveillance_Err_PRG.htm">Surveillance_Err_PRG</a></tspan>
經過研究,我編寫了以下代碼,但是它什么都不做(輸出僅顯示我的代碼):
$directory = "C:\Users\jacka\Desktop\Organigramme_PLC_prog_test\"
$list = "$directory" + "list.txt"
$htms = "$directory" + "HTMs"
$htmFiles = Get-ChildItem $directory *.htm -rec
foreach ($file in $htmFiles)
{
foreach($line in Get-Content $list)
{
if($line -match $regex)
{
$fichier = "$htms\"+"$line"+".htm"
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace "$line", "<a href=""$htms\$line"">$line</a>" } |
Set-Content $file.PSPath
}
echo $fichier
}
}
在那之前,我是這樣的:
foreach($line in Get-Content $list) {
if($line -match $regex){
$fichier = "$htms\"+"$line"+".htm"
(Get-Content $fichier).replace("$line", "<a href=""$fichier"">$line</a>") | Set-Content $fichier
echo $fichier
}
}
它實際上並沒有用,因為它只是在內部標題上放置了一個鏈接(每個htm中的文檔名稱都顯示在頂部)。
因此,我知道很多信息(但是我想提供盡可能多的信息),很抱歉,如果我不清楚,但是基本上我想使上面的代碼適用於文件夾中的每個文件。
提前致謝!
所以我找到了解決方案
首先,我在那里遇到問題
$htmFiles = Get-ChildItem $directory *.htm -rec
foreach ($file in $configFiles)
變量不一樣,但是我得到了這個錯誤:
C:\Users\jacka\Desktop\Organigramme_PLC_prog_test\HTMs\Systeme_Filtration_Prg.htm
Get-Content : Impossible de trouver le chemin d'accès « C:\Users\jacka\ChargementProg_PRG.htm », car il n'existe pas.
Au caractère Ligne:22 : 14
+ (Get-Content $file) |
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\jacka\ChargementProg_PRG.htm:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
我通過在$ file之后添加.FullName來解決此問題,這阻止了Get-Content嘗試從當前目錄訪問文件 :
$htmFiles = Get-ChildItem $directory *.htm -rec
foreach ($file in $htmFiles)
{
foreach($line in Get-Content $list)
{
if($line -match $regex)
{
$fichier = "$directory"+"$line"+".htm"
if ($file.FullName -ne $fichier) #to prevent header to be changed
{
(Get-Content $file.FullName) |
Foreach-Object { $_ -replace "$line", "<a href=""$fichier"">$line</a>" } |
Set-Content $file.FullName
}
}
}
echo "$file.FullName is done"
}
由於您沒有包括整個文件,因此我創建了一個簡單的source.html
文件:
<html>
<head>
<title>Website</title>
</head>
<body>
<tspan x="53" y="54.8">Surveillance_Err_PRG</tspan>
</body>
</html>
接下來的問題是解析HTML 。 如評論中所述,regexp 不是解析html的好方法。 在我看來,如果您的HTML頁面/網站相當復雜,最好的解決方案是使用最初用於.NET的 html敏捷包 ,但也可以針對powershell進行調整。
對於您的示例,要獲得最終結果,您必須像這樣進行操作:(注意: 不要忘記更改HtmlAgilityPack.dll的路徑)
Add-Type -Path 'C:\prg_sdk\nuget\HtmlAgilityPack.1.7.2\lib\Net40-client\HtmlAgilityPack.dll'
$doc = New-Object HtmlAgilityPack.HtmlDocument
$result = $doc.Load('C:\prg\PowerShell\test\SO\source.html')
$text = $doc.DocumentNode.SelectNodes("//tspan").InnerHTML
write-host $text
$out_text = $doc.DocumentNode.SelectNodes("//tspan").OuterHTML
write-host $out_text
$element = $doc.CreateTextNode("<a href=""c:\<your_path>\HTMs\$text.htm"">$text</a>")
$doc.DocumentNode.SelectSingleNode("//tspan").InnerHTML = $element.InnerText
$changed_text = $doc.DocumentNode.SelectSingleNode("//tspan").OuterHTML
Write-host "Adjusted text:" $changed_text
write-host 'whole HTML:' $doc.DocumentNode.SelectSingleNode("//tspan").OuterHtml
# To overview whole HTML
write-host 'whole HTML:' $doc.DocumentNode.InnerHTML
寫主機將產生您的期望:
<tspan x="53" y="54.8"><a href="c:\\<your_path>\\HTMs\\Surveillance_Err_PRG.htm">Surveillance_Err_PRG</a></tspan>
要在文件中查找字符串,您可以執行以下操作(只是一個片段):
$html_files= Get-ChildItem . *.htm -rec
foreach ($file in $html_files)
{
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace "$out_text", "$changed_text" } |
Set-Content $file.PSPath
}
要將其放在一起,您將必須遍歷所有.htm
文件並將其替換為上述示例。 如果您想讓我們完成它,您將不得不給我完整的文件示例。 我已經在測試一個上做到了:
現在所有的東西看起來像這樣:
Add-Type -Path 'C:\prg_sdk\nuget\HtmlAgilityPack.1.7.2\lib\Net40-client\HtmlAgilityPack.dll'
$doc = New-Object HtmlAgilityPack.HtmlDocument
$result = $doc.Load('C:\prg\PowerShell\test\SO\source.html')
$text = $doc.DocumentNode.SelectNodes("//tspan").InnerHTML
$original_tag = $doc.DocumentNode.SelectNodes("//tspan").OuterHTML
$element = $doc.CreateTextNode("<a href=""c:\<your_path>\HTMs\$text.htm"">$text</a>")
$doc.DocumentNode.SelectSingleNode("//tspan").InnerHTML = $element.InnerText
$changed_tag = $doc.DocumentNode.SelectSingleNode("//tspan").OuterHTML
$html_files= Get-ChildItem . *.htm -rec
foreach ($file in $html_files)
{
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace "$original_tag", "$changed_tag" } |
Set-Content $file.PSPath
}
我希望源代碼清晰,我已嘗試使其具有可讀性(不要忘記更改所有變量)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.