Batch file 无法从另一个批处理文件中操作已解析的字符串,因为空格和引号将其打断

Batch file 无法从另一个批处理文件中操作已解析的字符串,因为空格和引号将其打断,batch-file,Batch File,我有一个批处理文件,它正在调用另一个批处理文件。批处理文件1正在将5个参数解析为批处理文件2 当我将参数从批处理文件1解析到批处理文件2时,它会正确解析,但当我将这些解析的参数分配给批处理文件2中使用时,它会中断 批处理文件1: ECHO SET sql=SELECT MAX("Date") FROM SQ_TEST."Sample - Superstore Ran"; SET pref=W SET num=0 SET day=Friday SET config=SampleSuperStore

我有一个批处理文件,它正在调用另一个批处理文件。批处理文件1正在将5个参数解析为批处理文件2

当我将参数从批处理文件1解析到批处理文件2时,它会正确解析,但当我将这些解析的参数分配给批处理文件2中使用时,它会中断

批处理文件1:

ECHO
SET sql=SELECT MAX("Date") FROM SQ_TEST."Sample - Superstore Ran";
SET pref=W
SET num=0
SET day=Friday
SET config=SampleSuperStore.txt
CALL Z:\XXX\RunTableauRefreshAutomatic.bat %sql% %pref% %num% %day% %config%
ECHO
SET sql=SELECT MAX("Date") FROM SQ_TEST."Sample - Superstore Ran";
SET pref=W
SET num=0
SET day=Friday
SET config=SampleSuperStore.txt
CALL Z:\XXX\RunTableauRefreshAutomatic.bat sql %pref% %num% %day% %config%
批处理文件2:

CALL C:\XXX\anaconda3\Scripts\activate.bat 
SET sql=%~1
SET pref=%~2
SET num=%~3
SET day=%~4
SET config=%~5
C:\XXX\anaconda3\python.exe Z:\XXX\pMainAutomaticDB.py %sql% %pref% %num% %day% %config%
PAUSE
setlocal enableDelayedExpansion
CALL C:\XXX\anaconda3\Scripts\activate.bat 
SET sql=!%~1!
SET pref=%~2
SET num=%~3
SET day=%~4
SET config=%~5

:: I doubt this next line works properly.
C:\XXX\anaconda3\python.exe Z:\XXX\pMainAutomaticDB.py !sql! %pref% %num% %day% %config%

:: You probably need to change your python script to read the sql value from an environment
:: variable so you can then pass the value by reference just as we did with batch.
::
:: C:\XXX\anaconda3\python.exe Z:\XXX\pMainAutomaticDB.py sql %pref% %num% %day% %config%
::
:: Otherwise you will need to escape your quote literals - I believe python uses `\"`

PAUSE
批处理文件2的响应:

CALL C:\XXX\anaconda3\Scripts\activate.bat 
SET sql=%~1
SET pref=%~2
SET num=%~3
SET day=%~4
SET config=%~5
C:\XXX\anaconda3\python.exe Z:\XXX\pMainAutomaticDB.py %sql% %pref% %num% %day% %config%
PAUSE
setlocal enableDelayedExpansion
CALL C:\XXX\anaconda3\Scripts\activate.bat 
SET sql=!%~1!
SET pref=%~2
SET num=%~3
SET day=%~4
SET config=%~5

:: I doubt this next line works properly.
C:\XXX\anaconda3\python.exe Z:\XXX\pMainAutomaticDB.py !sql! %pref% %num% %day% %config%

:: You probably need to change your python script to read the sql value from an environment
:: variable so you can then pass the value by reference just as we did with batch.
::
:: C:\XXX\anaconda3\python.exe Z:\XXX\pMainAutomaticDB.py sql %pref% %num% %day% %config%
::
:: Otherwise you will need to escape your quote literals - I believe python uses `\"`

PAUSE
Z:\XXX>呼叫 C:\XXX\anaconda3\Scripts\activate.bat

(基本)Z:\XXX>SET sql=SELECT

(基本)Z:\XXX>设置 pref=最大值(“日期”)

(基本)Z:\XXX>SET num=FROM

(基本)Z:\XXX>设置 天=SQ_测试。“样本-超市运行”

(基本)Z:\XXX>设置配置=W

(基数) Z:\XXX>C:\XXX\anaconda3\python.exe Z:\XXX\pmainutomaticdb.py 从DL_SQ_测试中选择最大值(“日期”)。“样本-超市运行”W

(基本)Z:\XXX>暂停按任意键 继续的关键

更新:当我删除sql中的双引号时,它会按预期工作,但我需要它们。 此外,我尝试使用^,但批处理文件2仍然以不同的方式破坏它

@echo off
setlocal
SET "sql=SELECT MAX("Date") FROM SQ_TEST.""Sample - Superstore Ran"";"
call :otherbatch "%sql%" two three
goto :eof

:otherbatch
@echo off
set "var=%~1"
set "var=%var:""="%"
echo one :%var%
echo two :%~2
echo thre:%~3
goto :eof
(无论是调用一个单独的批处理文件还是一个子例程,
都是一样的,所以我使用了后者来说明原理。)

诀窍是确保带有空格(或其他有毒字符)的部分正确引用。
不幸的是,这需要一些思考、计算和尝试。我认为没有一种安全的方法可以自动执行(除了很多代码)

为了这根特殊的绳子

SELECT MAX("Date") FROM SQ_TEST."Sample - Superstore Ran";
字符串
“%sql%”
变为:

"SELECT MAX("Date") FROM SQ_TEST."Sample - Superstore Ran";"
SiiiiiiiiiiiEooooSiiiiiiiiiiiiiiiEoooooooooooooooooooooooSiE
下一行显示字符串的一部分是inside还是oStart和End的正确引用的外侧。
下一步是确保每个
空格
(或任何其他分隔符)都被引用(inside),方法是在需要时添加引号(不是在空格本身周围,而是在包含空格的子字符串周围,使用已存在引号的位置)

这会将字符串更改为:

"SELECT MAX("Date") FROM SQ_TEST.""Sample - Superstore Ran"";"
SiiiiiiiiiiiEooooSiiiiiiiiiiiiiiiESiiiiiiiiiiiiiiiiiiiiiiiESoE
现在,每个空格都被正确引用(您可以看到,这很困难,因为其他“不相关”的部分可能会更改其内部/外部状态)。因此,它可以作为单个参数传递

当然,这意味着,在接收端有一些多余的引号,必须删除。我们可以用
替换每个
”,这样做很容易(至少在本例中是这样):


注意:这对于要处理的字符串非常具体,因此我尝试一步一步地解释要做什么。您必须重新考虑每个特定字符串的整个过程,我相信这种方法在某些组合中是无用的。

您可能会遇到更多的问题,而不仅仅是空格


有毒字符,如
&
|
,和
删除了我不正确的评论。