2013-04-03 65 views
0

預先感謝您的時間。PowerShell根據內容替換文本文件中的多個元素

我是PowerShell的新手,試圖編寫一個腳本,可以搜索一堆文本文件並挑選出某些元素,然後使用它們來替換其他元素。以下是內容的一個例子:

OrderLine="0002" <Image>11770060002_outside.jpg</Image><Image>11770060002_inside.jpg</Image> 
OrderLine="0003" <Image>11770060003_outside.jpg</Image><Image>11770060003_inside.jpg</Image> 

所以我想要做的就是一步通過,挑選出「訂單行」價值,並把它變成一個變量,然後更換「圖像」價值 - 它可能更容易只是顯示預期的輸出,而不是試圖解釋它!

OrderLine="0002" <Image>11770060002.pdf</Image> 
OrderLine="0003" <Image>11770060003.pdf</Image> 

正如您所看到的,文件名已被替換,並且名稱的末尾與OrderLine相同。文件中可能只有一個訂單行,或者可能有150個,但規則總是相同的。

我知道它看起來像XML,但它是無效的(不要問),所以它不會解析,因此需要是基於文本的解決方案。

感謝任何幫助!

編輯:這是我到目前爲止,這工作,但它從文件名(這是與文件中的第一個條目相同,即0001)的值,所以它只適用於具有單個訂單的文件。我需要更新例程來處理上面的多個OrderLine條目。

$File_Folder = "C:\PSTEST\TEST\" 
$Output_Folder = "C:\PSTEST\TEST\OUTPUT\" 

$array = Get-ChildItem $File_Folder\*.xml 

foreach($item in $array){ 

$xml_filename = $item.FullName.substring($File_Folder.Length) 

$just_filename = $xml_filename -replace ".xml", "" 
$just_filename = $just_filename -replace "Order_PO", "" 

$replace_outside_original = '<image>' + $just_filename + '_outside.jpg</Image>' 
$replace_outside_with = '<image>' + $just_filename + '.pdf</image>' 

$replace_inside_original = '<image>' + $just_filename + '_inside.jpg</Image>' 
$replace_inside_with = '' 

$destination_file = $Output_Folder + 'Order_PO' + $just_filename + '.xml' 

(Get-Content $File_Folder\$xml_filename) | Foreach-Object { 
    $_ -replace $replace_outside_original, $replace_outside_with ` 
     -replace $replace_inside_original, $replace_inside_with ` 
    } | Set-Content $destination_file 
} 
+0

jpg文件名的最後幾位總是與OrderLine匹配嗎?從這個例子來看,它似乎只是用'.pdf'替換'_outside.jpg',然後修剪掉最後一個Image元素。 – mjolinor

+0

是的 - 我可以用substring單獨做到這一點,我可以創建一個'替換'變量,並用一個空白字符串替換它,但問題是我無法解決如何讀取OrderLine值,然後第二個問題是如何繼續下去,直到我有每個條目。 –

+0

啊,@ mjolinor我明白你的意思,對不起 - 是的,你是對的 - 理論上我可以用.pdf替換_outside.jpg的所有例子,但是我想不出一種說法,關閉第二個圖像元素「,因爲第一個和第二個標籤是相同的,所以一個簡單的替換就不會這樣做。 –

回答

0

使用正則表達式:

與行的一個開始,你需要匹配:

訂單行= 「0002」 11770060002_outside.jpg11770060002_inside.jpg

替換變量用正則表達式元字符的部分。在這種情況下,可變數據數字:

$regex = 'OrderLine="\d+" <Image>\d+_outside.jpg</Image><Image>\d+_inside.jpg</Image>' 

然後添加分組對的括號你想保留的部分(S):

$regex = '(OrderLine="\d+" <Image>\d+_outside.jpg</Image>)<Image>\d+_inside.jpg</Image>' 

然後使用-match過濾掉了線匹配正則表達式,替換爲捕獲組的反引用來完成修剪,而另一個替換替換文本的文字部分,然後將結果輸出到另一個文件。

(get-content file.txt) -match $regex -replace $regex,'$1' -replace '_outside\.jpg','.pdf' | 
set-content newfile.txt 
+0

謝謝@mjolinor - 感謝您的幫助!我仍然在努力把它放到一個循環中,它將遍歷OrderLine值,直到完成所有這些值爲止,但我會繼續研究它 - 我可能錯過了一些明顯的東西,因爲我的大腦因爲看着這個而炸好幾天! –

+0

你不應該需要一個循環。 -match和replace操作符將一次處理整個數組,所以你不需要單步執行。 – mjolinor

+0

我真的很努力地想到這一點,這是漫長的一天!所以我有一個文件,其中包含名爲file.txt的原始樣式行,那麼它如何寫入新文件?當我嘗試運行你所說的線條時,它會輸出'False'或'True'。 –

0

成功!如果沒有mjolinor的幫助,我無法做到這一點,所以千名感謝您花時間幫助我,我真的很感激。

最後我通過替換一個,然後執行另一個替代,我認爲這是匹配聲明輸出真/假,我沒有技能來處理它。這種方式並不是最乾淨的,但它完成了工作:

$File_Folder = "C:\PSTEST\TEST\" 
$regex = '<Image>\d+_inside.jpg</Image>' 
$array = Get-ChildItem $File_Folder\*.xml | ForEach-Object { (Get-Content $_) -replace '_outside\.jpg','.pdf' | Set-Content -path $_ } 
$array = Get-ChildItem $File_Folder\*.xml | ForEach-Object { (Get-Content $_) -replace $regex,'' | Set-Content -path $_ } 
相關問題