我有一個 gpx 檔案,它只是 xml,并且想運行一個 powershell 腳本來洗掉 <time> 節點。
<trkpt lat="-33.483478" lon="150.159805">
<name> p2 </name>
<time>2021-02-23T00:00:12Z</time>
</trkpt>
<trkpt lat="-33.483852" lon="150.158309">
<name> p3 </name>
<time>2021-02-23T00:00:56Z</time>
</trkpt>
<trkpt lat="-33.483943" lon="150.157897">
<name> p4 </name>
<time>2021-02-23T00:01:07Z</time>
</trkpt>
<trkpt lat="-33.484066" lon="150.157592">
<name> p5 </name>
<time>2021-02-23T00:01:17Z</time>
</trkpt>
每行僅以 LF 或 \n 結尾。我想洗掉 <time> 節點,包括換行符。
我知道我有正確的換行符或 EOL,因為我可以在 Notepad 中清楚地看到這一點,并且其中的正則運算式完美運行<time>(.*?)</time>\n。
所以我使用帶有此代碼的powershell:
(gc test.gpx) -replace '<time>(.*?)</time>`n', '' | Out-File -encoding ASCII processed1.gpx
我所有的研究都表明 powershell 的換行符是 `n(不是\n)。我也試過`r`n雙引號"`n"或"`r`n"以防萬一,它只是不起作用。我搜索過類似的問題,他們的答案似乎對我不起作用。
幫助贊賞!
本
uj5u.com熱心網友回復:
注意:為了健壯性,最好使用專用的 XML 決議器來操作 XML,例如 .NET[xml] (System.Xml.XmlDocument)型別 - 請參閱底部部分。
至于你嘗試了什么:
Get-Content(gc)默認情況下逐行讀取檔案,并且由于結果行已從其中洗掉了任何尾隨換行符,因此-replace, 運算子根據定義找不到任何換行符來匹配 - 并且,因為提供了字串陣列(行)作為輸入,-replace操作在每一行上。- 添加
-Raw開關以完整讀取整個檔案,而不是作為單個多行字串。
- 添加
雖然您確實需要轉義序列
`n來表示 PowerShell 中的換行符 (LF),但這僅適用于可擴展(雙引號)字串 ("...")。- 雖然您可以將正則運算式的參考更改為
"...",但更好的方法是使用逐字(單引號)字串 ('...')并使用正則運算式轉義序列\n, 來表示換行符(PowerShell 只是將其傳遞給 .NET 正則運算式作為其正則運算式功能基礎的引擎,例如-replace運算子)。 - 此外,您可能希望使用
\r?\n它來處理 Windows 格式的 CRLF 和 Unix 格式的 LF-only 換行符。
- 雖然您可以將正則運算式的參考更改為
因此(請注意,省略替換字串與傳遞相同''):
(gc -Raw test.gpx) -replace '<time>(.*?)</time>\r?\n'
XML決議解決方案:
# Sample input, wrapped in a <xml> element.
# To load from a file, use. Load() with a *full file path*:
# ($xml = [xml]::new()).Load("$PWD/test.gpx")
($xml = [xml]::new()).LoadXml(@'
<xml>
<trkpt lat="-33.483478" lon="150.159805">
<name> p2 </name>
<time>2021-02-23T00:00:12Z</time>
</trkpt>
<trkpt lat="-33.483852" lon="150.158309">
<name> p3 </name>
<time>2021-02-23T00:00:56Z</time>
</trkpt>
<trkpt lat="-33.483943" lon="150.157897">
<name> p4 </name>
<time>2021-02-23T00:01:07Z</time>
</trkpt>
<trkpt lat="-33.484066" lon="150.157592">
<name> p5 </name>
<time>2021-02-23T00:01:17Z</time>
</trkpt>
</xml>
'@)
$xml.xml.ChildNodes.ForEach({
$parent = $_
$null = $parent.ChildNodes.
Where({ $_.name -eq 'time' }).
ForEach({ $parent.RemoveChild($_) })
})
# Use $xml.Save - with a full output file path - to save the modified XML:
# $xml.Save("$PWD/processed1.gpx")
注意:以上不會創建漂亮列印的XML 輸出,即任何原始的漂亮列印都丟失了。如果需要漂亮的列印,有兩種選擇:
在呼叫/之前在實體上設定
.PreserveWhitespace為- 但是,這可能會為洗掉的每個元素留下一個空行。$true[xml].Load().LoadXml()在保存時重新執行漂亮的列印 - 請參閱此答案的底部部分。
uj5u.com熱心網友回復:
在 gpx 檔案的目錄中打開一個 power shell
使用這個正則運算式: (?<=beginningstringname)(.*\n?)(?=endstringname)
運行這個命令
get-content test.gpx | %{$_ -replace "(?<=<time>)(.*?)(?=<\/time>)",""}
然后
獲取內容 test.gpx | %{$_ -replace "findText","re??placeText"}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/392509.html
