1 (изменено: danishru, 2014-02-08 22:24:56)

Тема: CMD/BAT: замена слов в XML файле

Доброго времени суток господа.

Начал я писать скрипт для автоматизации установки Windows из среды WinPE с пользовательским вводом информации, и столкнулся со следующей проблемой.

Есть xml файл, который является файлом ответа, с заранее заданными параметрами установки Windows, и мне необходимо что бы пользователь в интерактивном режиме, допустим с помощью переменных, изменял в этом файле некоторые слова, например $computername$, $username$ и $displayusername$ на русские и английские слова. Знак доллар можно заменить чем угодно, да и слова могут быть разными. BAT файл должен выполнятся в кодировке OEM-866.

Кусок исходного xml кода:


<LocalAccount wcm:action="add">
      <DisplayName>$displayusername$</DisplayName>
      <Group>Users</Group>
      <Name>$username$</Name>
</LocalAccount>

Кусок того, что хочу получить:


<LocalAccount wcm:action="add">
      <DisplayName>Вася Пупкин</DisplayName>
      <Group>Users</Group>
      <Name>vpupkin</Name>
</LocalAccount>

Кодировка xml файла utf-8, notepad++ показывает ANSI as utf-8, после внесения изменения файл должен отображаться в стандартном блокноте и браузере нормально, русские буквы должны отображаться без крякозябр, кодировка должна остаться такой же. Исходный файл должен остаться нетронутым, а новый должен называться unattend.xml и перемещен по заданному пути.

Для пользователя должно это выглядеть следующем образом.


1. Введите имя пользователя на латинице. Например vpupkin:
2. Введите отображаемое имя и фамилию пользователя. Например Вася Пупкин:
3. Введите имя компьютера. Например COMP-01:

Исходный xml файл прикладываю.

Post's attachments

source.xml 6.02 kb, 14 downloads since 2014-02-08 

You don't have the permssions to download the attachments of this post.

2

Re: CMD/BAT: замена слов в XML файле

Кодировка xml файла utf-8,

Используйте WSH или PoSH.

3

Re: CMD/BAT: замена слов в XML файле

danishru, насколько срочно?

alexii, если забыть про UTF-8 и думать, что всё в CP866, сделаете BAT? Я бы адаптировал под UTF-8.

4 (изменено: danishru, 2014-02-09 00:46:43)

Re: CMD/BAT: замена слов в XML файле

alexii пишет:

Кодировка xml файла utf-8,

Используйте WSH или PoSH.

Мне бы с CMD совладать бы, а вы про WSH или PowerShell.

5 (изменено: danishru, 2014-02-09 00:54:31)

Re: CMD/BAT: замена слов в XML файле

wisgest пишет:

danishru, насколько срочно?

alexii, если забыть про UTF-8 и думать, что всё в CP866, сделаете BAT? Я бы адаптировал под UTF-8.

Да не очень и срочно это, пока сделал открытие блокнота для изменений, но хотелось бы автоматизировать весь процесс, так как менять только 3 слова надо будет в основном.

Нашел я в интернете такой vbs скрипт, который меняет слово.


'============================================= 
 ' Замена текста в файле 
' 
 ' Параметры: 
 ' {файл} {текст для поиска} {текст для замены} 
 '============================================= 
Option Explicit 
 Dim FSO, F, Str1, Str2, Text 
 Set FSO = CreateObject("Scripting.FileSystemObject") 
 With WScript 
   F    = .Arguments(0) 
   Str1 = .Arguments(1) 
   Str2 = .Arguments(2) 
 End With 
 F = FSO.GetAbsolutePathName(CreateObject("WScript.Shell").ExpandEnvironmentStrings(F)) 

 Text = FSO.OpenTextFile(F, 1).ReadAll 
 Text = Replace(Text, Str1, Str2, 1, -1, 1) 
 FSO.OpenTextFile(F, 2).Write Text 

 Set FSO = Nothing 
 WScript.Quit 0

Но он не дружит с русским языком.

А запускаю я его с помощью BAT файла, с таким содержанием.

findrename3.vbs "source2.xml" "guid-01" "Петров"

Предварительно, я изменил название слов которые надо переименовать, то есть $displayusername$ поменял на guid-01, так как идея использовать $ была глупой. )

6 (изменено: Rumata, 2014-02-09 01:51:16)

Re: CMD/BAT: замена слов в XML файле

Попробуйте так:


@echo off

setlocal

set "FILE_SRC=source.xml"
set "FILE_DST=unattend.xml"

set /p "val_username=Введите имя пользователя на латинице. Например vpupkin: "
set /p "val_displayusername=Введите отображаемое имя и фамилию пользователя. Например Вася Пупкин: "
set /p "val_computername=Введите имя компьютера. Например COMP-01: "

call :read_and_replace "%FILE_SRC%" >"%FILE_DST%"

endlocal
goto :EOF


:read_and_replace
setlocal enabledelayedexpansion

chcp 65001>nul

for /f "usebackq tokens=1,2,3 delims=$" %%a in ( "%~1" ) do (
    if "%%~b" == "" (
        echo:%%a
    ) else (
        set "v=!val_%%b!"
        echo:%%a!v!%%c
    )
)

endlocal
goto :EOF

Скрипт основывается на предположении, что все изменяемые теги располагаются каждый на отдельной строке. Название слов которые надо переименовать, то есть $displayusername$ можно оставить как и было прежде. В переменные FILE_SRC и FILE_DST пропишите реальные пути к исходному и результирующему файлам.

( 2 * b ) || ! ( 2 * b )

7

Re: CMD/BAT: замена слов в XML файле

wisgest пишет:

alexii, если забыть про UTF-8 и думать, что всё в CP866, сделаете BAT?

Не вижу большого смысла делать на пакетных файлах при наличии технологии, специально предназначенной для обработки xml-файлов — подводных камней слишком много. Так что — я пас.

8

Re: CMD/BAT: замена слов в XML файле

alexii пишет:

при наличии технологии, специально предназначенной для обработки xml-файлов

Тут скорее обработка простого текста, обход DOM скорее запутает задачу, чем поможет.
Кстати, как работать с utf-8 в WSH? Не представляю как через FSO. Через ADO?

9 (изменено: wisgest, 2014-02-09 02:16:19)

Re: CMD/BAT: замена слов в XML файле

Rumata,

chcp 65001>nul

будет работать не на всех системах. У меня, например, скрипт тихо завершит работу, если только это не часть составной команды, в конце которой кодировка меняется обратно.

Да, и как помнится, если переключить кодировку внутри команды, вывод которой перенаправлен, больше ничего выведено не будет.

10 (изменено: danishru, 2014-02-09 02:23:23)

Re: CMD/BAT: замена слов в XML файле

Rumata пишет:

Попробуйте так:


@echo off

setlocal

set "FILE_SRC=source.xml"
set "FILE_DST=unattend.xml"

set /p "val_username=Введите имя пользователя на латинице. Например vpupkin: "
set /p "val_displayusername=Введите отображаемое имя и фамилию пользователя. Например Вася Пупкин: "
set /p "val_computername=Введите имя компьютера. Например COMP-01: "

call :read_and_replace "%FILE_SRC%" >"%FILE_DST%"

endlocal
goto :EOF


:read_and_replace
setlocal enabledelayedexpansion

chcp 65001>nul

for /f "usebackq tokens=1,2,3 delims=$" %%a in ( "%~1" ) do (
    if "%%~b" == "" (
        echo:%%a
    ) else (
        set "v=!val_%%b!"
        echo:%%a!v!%%c
    )
)

endlocal
goto :EOF

Скрипт основывается на предположении, что все изменяемые теги располагаются каждый на отдельной строке. Название слов которые надо переименовать, то есть $displayusername$ можно оставить как и было прежде. В переменные FILE_SRC и FILE_DST пропишите реальные пути к исходному и результирующему файлам.

Большое вам спасибо, скрипт отработал на ура.

Я правильно понимаю, что бы добавить к этому скрипту новую переменную, то мне достаточно добавить новую set /p, и в

usebackq tokens=1,2,3 

добавить цифру 4? Я так понимаю что usebackq tokens отвечает за введённые ранее переменные? И что изменить в коде, если я хочу убрать знаки $?

11

Re: CMD/BAT: замена слов в XML файле

Чтобы добавить новую перменную достаточно добавить только строку ивда

set /p "newvarname=введите значение newvarname: "

фрагмент кода

usebackq tokens=1,2,3 delims=$

отвечает за разделение строки на ТРИ подстроки и их размещение по параметрам цикла. Этот код предполагает, что входная строка выглядит ТОЧНО так как показано ниже

начало$середина$конец

.

Символ $ несет "смысловую нагрузку" - он служит разделителем подстрок. При этом средняя часть ("середина" в примере выше) является именем переменной (как например newvarname в примере еще выше). Если Вы удалите этот символ, то Вам потребуется ввести какй-то другой символ в качетсве разделителя. ПРи этом он не должен пересекаться с другими символами файла source.xml.

( 2 * b ) || ! ( 2 * b )

12 (изменено: wisgest, 2014-02-10 12:42:19)

Re: CMD/BAT: замена слов в XML файле

Может, кому-нибудь будет интересно моё решение.
Вместо $ должны использоваться восклицательные знаки (если в source.xml потребуется использовать восклицательный знак сам по себе, его надо предварять ^).
В качестве имён подставляемых переменных не следует использовать !count! и !line!, т.к. они используются во внутренних целях.
Не учтена возможность ввода пользователем символов специальных для XML.

(10.02.2014: В присоединённый архив включен файл source.xml с $ заменёнными на !; ниже приведён код командного файла, содержащего непечатные знаки — для запуска брать файл из присоединённого архива.)

+ открыть спойлер
@echo off
if "%~1"=="/UTF16" goto UTF16
setlocal enableextensions enabledelayedexpansion
call :Input
(
cmd.exe /a /d /c set /p p= ?<nul
cmd /u /v /d /c "%~f0" /UTF16
)>utf16.tmp
chcp 65001>nul & cmd /a /d /c type utf16.tmp >utf8.tmp & chcp 866>nul
call :Input >nul <utf8.tmp
del utf16.tmp utf8.tmp
call :SUB <source.xml >unattend.xml
endlocal
exit /b
::------------------

:Input
set /p "username=Введите имя пользователя на латинице. Например vpupkin: "
set /p "displayusername=Введите отображаемое имя и фамилию пользователя. Например Вася Пупкин: "
set /p "computername=Введите имя компьютера. Например COMP-01: "
exit /b

:UTF16
:: Здесь перечислите все переменные в том же порядке, что и при вводе:
echo:!username!
echo:!displayusername!
echo:!computername!
exit /b

:SUB
for /f %%n in ('find.exe /c /v ""^<source.xml') do set count=%%n
:sub.loop:
if %count%==0 exit /b
    set "line="
    set /p "line="
    if defined line (
        set "line=!line:^=^^!"
        set line=!line:^"^=^^^"!
        set "line=!line:&=^&!"
        set "line=!line:|=^|!"
        set "line=!line:<=^<!"
        set "line=!line:>=^>!"
    )
    echo:%line%
set /a count-=1
goto sub.loop
Post's attachments

1.zip 2.27 kb, 5 downloads since 2014-02-10 

You don't have the permssions to download the attachments of this post.

13

Re: CMD/BAT: замена слов в XML файле

wisgest пишет:

Кстати, как работать с utf-8 в WSH?

В данном случае — просто «XmlDocument.load()».