2016-08-29 9 views
1

各XMLファイルに "00000000-0000-0000-0000-000000000000"の属性 "parentid"フォルダ内にある。拡張子のない各ファイルの実際のファイル名は、XMLの「parentid」属性を置き換える必要があります。 (PowerShellのまたはバッチファイル)ファイル名を属性値(PowershellまたはBatch File)として使用するXML属性の検索と置換

例:C:\フォルダ\

4de6d1b4-b014-4cb3-bb61-649737a8217b.xml
4d2345b4-b415-5656-12dv-832jnm89234n.xml
。 ... XMLの

内容:

<comment id="4de6d1b4-b014-4cb3-bb61-649737a8217b" parentid="00000000-0000-0000-0000-000000000000" approved="True"> 
     <date>2014-12-20 22:23:40</date> 
     <author>Joe Doe</author> 
     <email>[email protected]</email> 
     <country /> 
     <ip>0.0.0.0</ip> 
     <avatar /> 
     <content>Test</content> 
    </comment> 

が、私はすべての人の助けに感謝!

これはこれまでの説明ですが、属性の実際の値ではなく、行全体が置き換えられます。

@echo off &setlocal 
setlocal enabledelayedexpansion 

set "search=00000000-0000-0000-0000-000000000000" 
set "replace=%%~nP" 
set "textfile=%%~nxP" 
set "newfile=%%~nP" 
for /r %%P in (*) do (
(for /f "delims=" %%i in (%textfile%) do (
    set "line=%%i" 
    set "line=!line:%search%=%replace%!" 
    echo(!line!))>"%newfile%" 
) 
) 
endlocal 


@ECHO ON 

答えて

1

基本的な問題は、あなたが、私はお勧めしませんfor変数、すなわち%%P、ループ範囲の外に言及していることです。純粋なバッチスクリプトで

、私はこのようにコードを変更します

@echo off 
setlocal EnableExtensions DisableDelayedExpansion 

set "SEARCH=00000000-0000-0000-0000-000000000000" 
for %%P in ("*.xml") do (
    for /F "delims=" %%I in (' 
     findstr /N /R "^" "%%~P" ^& ^> "%%~fP" break 
    ') do (
     set "LINE=%%I" 
     setlocal EnableDelayedExpansion 
     set "LINE=!LINE:*:=!" 
     if defined LINE set "LINE=!LINE:%SEARCH%=%%~nP!" 
     >> "%%~fP" echo(!LINE! 
     endlocal 
    ) 
) 
endlocal 
exit /B 

これは、直接、現在のディレクトリに列挙*.xmlファイルを変更することができるので、何の暫定ファイルはの交換を行うために必要とされません属性parentid

各ファイルは、行番号とコロンで一時的に空行を失わないように、すべての行に先行して読み取られます(for /Fは無視します)。その後、コマンドラインset "LINE=!LINE:*:=!"が接頭辞を削除します。遅延拡張は、ファイル内で感嘆符が失われないように、for /Fで切り替えられます。これらの措置により、元の*.xmlファイルの内容は変更されませんが、置き換えられた部分はもちろんです。

+0

これは完璧に動作しています! –

1

ありPowerShellでXMLファイルを解析ロードの例の多くは/ですが、この1のような単純なケースでは最速のソリューションは、保持している文字列に置き換える/プレーンテキスト検索を使用することですファイル全体:

$searchFor = 'parentid="00000000-0000-0000-0000-000000000000"' 
Get-ChildItem -Literal 'c:\folder' -Filter '*.xml' -Recurse | 
    Where { 
     Select-String $searchFor -Path $_ -CaseSensitive -SimpleMatch 
    } | 
    ForEach { 
     $text = [IO.File]::ReadAllText($_.FullName) 
     $text.replace($searchFor, 'parentid="' + $_.BaseName + '"') | 
      Out-File (Join-Path $_.Directory "$($_.BaseName)-new.xml") -Encoding utf8 
    } 
+0

私はPS v2を持っているので、-Rawモードが私のために働いていないようです。私は得る: Get-Content:-Rawと一致するパラメータが見つかりません –

+0

私はv2の場合、どうすればよいでしょうか。申し訳ありませんが、私はこれに少し新しいです。 –

+0

'(Get-Content -Raw $ _。FullName)の代わりに' [IO.File] :: ReadAllText($ _。FullName) 'を使用してください。私は数年前にPS4.0に切り替えたので、PS2の存在を考え続けるのは難しいです。私は答えを更新します。 – wOxxOm

関連する問題