Почему в массиве строк, выводимых пакетным файлом Windows, отсутствуют специальные символы? - PullRequest
0 голосов
/ 04 октября 2018

Я хочу вставить данные (только строки с расширенным ключевым словом), присутствующие в файле .txt, в базу данных Oracle в формате ID, Данные, Дата, Имя проекта , где присутствуют идентификатор, дата и имя проекта впеременные окружения.

File.txt содержит данные ниже:

Writing main object(name=abc)
writing Extended object (name=%abc(123&rest,type=pqr)

logdata.txt должен иметь данные ниже:

A1234C,(name=%abc(123&rest,type=pqr),12022018_11:12:20,DEV:Sales Project

При копировании данных в выходном файле отсутствуют специальные символы, такие как% (и т. Д., Присутствующие в файле file.txt) logdata.txt.

Ниже приведен код:

set file=D:\MSTR_CICD\file.txt
for /F "usebackq tokens=2*delims=(" %%a in (`findstr  "extended" "%file%"`) do (
    set /A i+=1
    call set array[%%i%%]=%%a
    call set n=%%i%%
)

for /L %%i in (1,1,%n%) do call echo %User_ID%,%%array[%%i]%%,%Timestamp%,%proj%  >> D:\MSTR_CICD\Batch_Script\logdata.txt

Пожалуйста, исправьте код или дайте мне знать, как мне этого добиться. Кроме того, мой входной файл может иметь любой специальный символ, поскольку он содержит журналы приложения.

1 Ответ

0 голосов
/ 05 октября 2018

Этот пакетный файл можно использовать для этой задачи:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "proj=DEV:Sales Project"
set "User_ID=A1234C"
set "Timestamp=12022018_11:12:20"
set "InputFile=D:\MSTR_CICD\file.txt"
set "DataFile=D:\MSTR_CICD\Batch_Script\logdata.txt"

if exist "%InputFile%" (
    for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /I /C:Extended "%InputFile%"') do (
        set "DataLine=%%I"
        setlocal EnableDelayedExpansion
        set "DataLine=!DataLine:*(=(!"
        set "DataLine=!DataLine:"=""!"
        echo %User_ID%,"!DataLine!",%Timestamp%,%proj%
        endlocal
    )
) >"%DataFile%"

if exist "%DataFile%" for %%I in ("%DataFile%") do if %%~zI == 0 del "%DataFile%"

:EndBatch
endlocal

FINDSTR выполняется в отдельном командном процессе, запущенном FOR в фоновом режиме с cmd.exe /Cрегистронезависимый, буквальный поиск строки Extended во входном файле и выводит все строки, содержащие эту строку для обработки STDOUT .

FOR , фиксирует этот выводи обрабатывает их построчно. FOR игнорирует пустые строки и по умолчанию также строки, начинающиеся с точки с запятой, поскольку ; является символом конца строки по умолчанию.И FOR разбивает строку на подстроки (токены), используя пробел / табуляцию в качестве разделителя, и назначает только первую подстроку указанной переменной цикла по умолчанию.

Используя FOR опция строки delims^=^ eol^= пустой список разделителей и без символа конца строки устанавливается для отключения разделения строк и игнорирования строк, начинающихся с точки с запятой.Поскольку эта строка специального параметра не может быть заключена в двойные кавычки, необходимо экранировать пробел и два знака равенства с символом вставки, чтобы эти три символа находились вне строки аргумента с двойными кавычками, интерпретируемой как буквенные символы, а не как разделители строк аргумента.

Вся строка в виде FINDSTR , найденная в файле, присваивается переменной окружения DataLine.Это делается с помощью отложенного расширения переменной среды, отключенного для обработки правильных строк, содержащих один или несколько восклицательных знаков.В противном случае cmd.exe будет дважды анализировать строку set "DataLine=%%I" после замены %%I на текущую строку и будет интерпретировать каждый ! в строке как начало / конец ссылки на переменную среды, что приведет к нежелательному изменению строки перед назначениемэто к переменной среды.

Использование команды CALL в строке с командой SET также приводит к двойному анализу командной строки перед выполнением команды SET . Именно поэтому некоторые символы отсутствуют в массиве переменных среды, создаваемом вашим кодом.

Подробнее см. Также Как синтаксический анализ сценариев командных интерпретаторов Windows (CMD.EXE)?

После назначения строки переменной среды необходимо включить отложенное расширение для дальнейшей обработки строки данных в цикле FOR .Это делает пакетный файл медленным, но его нельзя избежать в этом случае.Прочитайте этот ответ для получения подробной информации о командах SETLOCAL и ENDLOCAL .

Первая модификация в строке данных удаляет все, что осталось первым (.

Вторая модификация в строке данных заменяет все " на "" в строке, чтобы избежать каждой двойной кавычки согласно спецификации CSV.

Затем оставшаяся строка данныхвыводится вместе с другими данными, заключенными в двойные кавычки, поскольку строка данных может содержать также одну или несколько запятых, для которых согласно спецификации CSV требуется, чтобы данные были заключены в двойные кавычки.

Для спецификации CSV прочитайте, например,Статья в Википедии о значениях, разделенных запятыми .

Все, что выводится ECHO внутри цикла FOR , перенаправляется в указанный файл данных, который перезаписывает наВероятно, уже существующий файл данных с таким же именем.

Возможно, что FINDSTR не найдет ни одной строкиning Extended в любом случае приводит к созданию файла данных с 0 байтами.Пустой файл данных удаляется вторым FOR .

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

  • del /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...