Существует множество проблем, которые усложняют вашу задачу, если ее невозможно достичь с помощью пакета.
- Файл JSON, вероятно, будет закодирован как UTF-8, с чем неудобно работать в пакетном режиме.
SET /P
может читать только одну строку или 1021 символ, в зависимости от того, что произойдет раньше.
FOR /F
может использоваться для чтения нескольких строк, и значения могут быть объединены. Но объединение требует одного из двух вариантов, каждый со своими проблемами
- Можно использовать нормальное процентное расширение, но тогда такие символы, как
&
, |
, <
и т. Д., Могут вызвать проблемы, если данные также содержат литералы "
. Кроме того, для расширения в процентах потребуется хотя бы один CALL
, что может привести к удвоению цитируемых ^
символов.
- Можно использовать отложенное расширение, но тогда расширение
FOR /F
повредит !
и, возможно, ^
в данных, если они не будут экранированы первыми.
- Использование batch для выхода
!
требует расширения в процентах, что также может вызвать проблемы с отравленными символами.
- Пакет (cmd.exe) может работать только с переменными среды, максимальная длина которых составляет 8191 символ. ОС может обрабатывать намного больше, но пакет не может использовать такие большие значения. Для этого ограничения партии просто нет обходного пути.
Ниже приведен пример JSON с некоторыми дополнительными символами, добавленными для введения всех вышеперечисленных сложностей (кроме ограничения длины).
test.json (кодировка utf-8)
{
"type": "service_account\nline2",
"project_id": "myproject €! \"<^>\"",
"private_key_id": "sfackq0355ggeskvcPAFKCADACsdfa",
"private_key": "-----BEGIN PRIVATE KEY----- AAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSUGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XAt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/EnmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbxNrRFi9wrf+M7Q==",
"client_email": "myemail@mydomain.com",
"client_id": "45844444558569745",
"auth_uri": "url goes here ^",
"token_uri": "another url here ^"
}
Если предположить, что ваш JSON <8191 символов и закодирован как UTF-8 (или ASCII), тогда будет работать следующий чистый код пакета. </p>
@echo off
setlocal enableDelayedExpansion
:: Create a linefeed variable
set ^"LF=^
%= Generates a linefeed character =%
^"
:: Save active code page
for /f "tokens=2 delims=:." %%P in ('chcp') do set CHCP=%%P
:: Set active code page to UTF-8
chcp 65001 >nul
:: Read the file into str
set "str="
for /f usebackq^ delims^=^ eol^= %%A in ("test.json") do call :StoreLine
:: Restore active code page
chcp %CHCP% >nul
:: Show the result
set str
exit /b
:StoreLine
:: Safely escapes all ^ as ^^ and ! as ^! before appending %ln%!LF! to !str!
setlocal disableDelayedExpansion
for %%. in (.) do set "ln=%%A"
set "ln=%ln:"=""%"
set "ln=%ln:^=^^%"
set "ln=%ln:!=^!%"
endlocal & set "ln=%ln%" !
set "str=!str!!ln:""="!!LF!"
exit /b
Если вы не заботитесь о сохранении форматирования пробелов, тогда будет работать следующий упрощенный код (я также удалил комментарии). Обратите внимание, что символы новой строки, начальные пробелы и табуляции удаляются, но другие пробелы в строке сохраняются.
@echo off
setlocal enableDelayedExpansion
for /f "tokens=2 delims=:." %%P in ('chcp') do set CHCP=%%P
chcp 65001 >nul
set "str="
for /f "usebackq tokens=*" %%A in ("test.json") do call :StoreLine
chcp %CHCP% >nul
set str
exit /b
:StoreLine
:: Safely escapes all ^ as ^^ and ! as ^! before appending %ln%!LF! to !str!
setlocal disableDelayedExpansion
for %%. in (.) do set "ln=%%A"
set "ln=%ln:"=""%"
set "ln=%ln:^=^^%"
set "ln=%ln:!=^!%"
endlocal & set "ln=%ln%" !
set "str=!str!!ln:""="!"
exit /b
- ВЫХОД -
str={"type": "service_account\nline2","project_id": "myproject €! \"<^>\"","private_key_id": "sfackq0355ggeskvcPAFKCADACsdfa","private_key": "-----BEGIN PRIVATE KEY----- AAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSUGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XAt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/EnmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbxNrRFi9wrf+M7Q==","client_email": "myemail@mydomain.com","client_id": "45844444558569745","auth_uri": "url goes here ^","token_uri": "another url here ^"}
Любое из указанных выше решений для пакетной обработки требует включения отложенного расширения. Можно написать дополнительный код для переноса переменной через барьер ENDLOCAL. Но я бы не стал беспокоиться.
Вы можете использовать мою утилиту обработки текста JREPL.BAT для хранения текста в переменной, и это работает независимо от того, включено замедленное расширение или нет. JREPL.BAT - это гибридный JScript / пакетный скрипт, использующий механизм Windows CSCRIPT. Это чистый скрипт, который изначально запускается на любой машине с Windows, начиная с XP.
call jrepl.bat "^" "" /f "test.json|utf-8" /rtn str
Вы можете использовать возможность поиска / замены, чтобы полностью удалить все пробелы форматирования.
call jrepl "\q[\c\q]*\q|\s" "$&|" /m /xseq /t "|" /f "test.json|utf-8" /rtn str
- РЕЗУЛЬТАТ -
str={"type":"service_account\nline2","project_id":"myproject €! \"<^>\"","private_key_id":"sfackq0355ggeskvcPAFKCADACsdfa","private_key":"-----BEGIN PRIVATE KEY----- AAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSUGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XAt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/EnmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbxNrRFi9wrf+M7Q==","client_email":"myemail@mydomain.com","client_id":"45844444558569745","auth_uri":"url goes here ^","token_uri":"another url here ^"}
Параметр /F
можно изменить для поддержки практически любой кодировки. На моей машине JREPL (CSCRIPT) по умолчанию использует windows-1252, если кодировка не указана.
Теперь я бы не рекомендовал получать JREPL.BAT только для этой цели. Но JREPL - чрезвычайно мощный инструмент обработки текста. Если вам часто хочется манипулировать текстом или файлами с помощью пакета, JREPL может стать бесценным инструментом.