我刚刚开始使用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中,顶部显示的文档名称)。
所以我知道有很多信息(但我想提供尽可能多的信息),如果我不清楚,我很抱歉,但基本上我想让上面的代码适用于每个文件我的文件夹。
提前致谢!
答案 0 :(得分:2)
所以我找到了解决方案
首先,我遇到了问题
$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 trying to access the file from current directory:
$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"
}
答案 1 :(得分:2)
由于您没有包含整个文件,因此我创建了一个简单的source.html
文件:
<html>
<head>
<title>Website</title>
</head>
<body>
<tspan x="53" y="54.8">Surveillance_Err_PRG</tspan>
</body>
</html>
接下来,您遇到的问题是解析 HTML 。正如评论中所述,regexp是 NOT 解析html的好方法。在我看来,如果你有一个相当复杂的html页面/网站等,最好的解决方案是使用最初用于 .NET 的html agility pack,但也可以针对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
}
我希望源代码是清楚的,我试图使其可读(不要忘记更改所有变量)。