2017-12-05 20 views
0

XMLファイルを取り込んでスクリプトを作成しようとしています。一致する条件を探します。新しい行のアスタリスクが追加されたら、ファイルを調べてすべてのXMLタグを削除し、プレーンテキストファイルのデータ。このPowerShellスクリプトをより効率的にするにはどうすればよいですか?

スクリプトは小さな入力XMLファイルでテストされていますが、大丈夫ですが、大規模なXMLファイルを渡すと永遠になります(1時間以上実行しても、私はちょうどそれを停止した)。

私は非常に非効率な方法で仕事をしているに違いないと思っています。

# Takes input XML File, cleans up XML elements, outputs plain text file 

$FileName = "C:\Users\someguy\Desktop\input.xml" 
$Pattern = "ProcessSpecifier = ""true""" 
$FileOriginal = Get-Content $FileName 

[String[]] $FileModified = @() 
Foreach ($Line in $FileOriginal) 
{ 
    $FileModified += $Line 
    if ($Line -match $Pattern) 
    { 
     #Add Lines after the selected pattern 
     $FileModified += "*************isActive=true*****************"  
    } 
} 


$FileModified -replace "<[^>]+>", "" | Out-File C:\Users\someguy\Desktop\Output.txt 
+0

'+ = $ Line'はあなたがそれを呼び出すたびに新しい配列を作成します。 ArrayListを試してください。 –

+1

対象とするPowerShellのバージョンは? –

+0

私たちが話しているファイルのサイズのおおよその見積もりはありますか? – whatever

答えて

3

のは、背後にある外観と、ここで物事をスピードアップするために正規表現の束と一緒に行きましょう。ここでは

は、以下のスクリプトがあります。また、私はメモリにすべてを格納するつもりはない、私はちょうど助ける必要がパイプラインを渡すつもりです。私は行の先頭と末尾から空白を削除し、空白行を取り除きますが、必要に応じてその行を削除することができます。

# Takes input XML File, cleans up XML elements, outputs plain text file 

$FileName = "C:\Users\someguy\Desktop\input.xml" 
$Pattern = '(?<=^.*ProcessSpecifier = "true".*$)' 
(Get-Content $FileName) -replace $Pattern, "`n*************isActive=true*****************" -replace '<[^>]+?>' -replace '^\s*|\s$' | ?{$_} | Set-Content C:\Users\someguy\Desktop\Output.txt 

ので、ここでの主なものは、私はあなたのパターンのテキストを見つけるために後ろを見て使用することで、その行に新しい行とアスタリスクの行を追加します。ライン

<SomeTag>ProcessSpecifier = "true"</SomeTag> 

はなるように:

<SomeTag>ProcessSpecifier = "true"</SomeTag>`n*************isActive=true***************** 

二重引用符の内部で使用する場合、 `nは続いバッククォートは、新しい行を作成し、その「*********** ** isActive = true **************** 'は、検索パターンの直後の行に表示されます。 XMLタグを削除してから、任意の行の先頭または末尾の空白を削除します。

は、正規表現の置換後、私は空白行を削除しWhereステートメントに結果を渡し、その後、私はOut-Fileより外の優れたパフォーマンスを見てきましたSet-Contentに残りの行を渡します。 TheMadTechnicianの答えの

+0

これは完全に機能しました。ありがとうm8大いに感謝 – SirLearnAlot

1

バリエーション:

# Takes input XML File, cleans up XML elements, outputs plain text file 

$FileName = "C:\Users\someguy\Desktop\input.xml" 
$Pattern = '(?<=^.*ProcessSpecifier = "true".*$)' 
Set-Content -Path C:\Users\someguy\Desktop\Output.txt -Value (((Get-Content $FileName) -replace $Pattern, "`n*************isActive=true*****************" -replace '<[^>]+?>' -replace '^\s*|\s$').Where{$_}) 

私は実際にパイプラインを回避しようと、それはかなり遅い知る限りです。もちろん、ファイルが非常に大きい場合は、メモリ消費量に問題があります。 "().Where"構文は、すべてのPowerShellバージョン(バージョン4+ iirc)では機能しません。

これは推測ですが、実際にTheMadTechnician'sよりも高速かどうかはわかりません。私は結果に興味があります:)

+0

努力を感謝していただきありがとうございます:) – SirLearnAlot

関連する問題