Batch file cmd batch-usebackq in for:要拆分的字符串从逗号分隔改为空格分隔
我想读取一个字符串,其中包含卡夫卡的多个主机(数量未终止),并用cmdBatch file cmd batch-usebackq in for:要拆分的字符串从逗号分隔改为空格分隔,batch-file,cmd,echo,Batch File,Cmd,Echo,我想读取一个字符串,其中包含卡夫卡的多个主机(数量未终止),并用cmdfor将它们分别列在单独的行中 字符串类似于: host1:9092,host2:9092,host3:9092,... 我得到的是: set /p BOOTSTRAPSERVERS="Bootstrap servers with port, separated by comma(by default localhost:9092): " REM echo "%BOOTSTRAPSERVERS%" if "%BOOTSTRA
for
将它们分别列在单独的行中
字符串类似于:
host1:9092,host2:9092,host3:9092,...
我得到的是:
set /p BOOTSTRAPSERVERS="Bootstrap servers with port, separated by comma(by default localhost:9092): "
REM echo "%BOOTSTRAPSERVERS%"
if "%BOOTSTRAPSERVERS%"=="" set BOOTSTRAPSERVERS="localhost"
echo All the servers to connect:
FOR /F "usebackq delims=," %%i in (`echo %BOOTSTRAPSERVERS%`) do (
echo %%i
echo.
)
但是,我只在一行中获取所有主机,空间分隔:
All the servers to connect:
host1:9092 host2:9092 host3:9092
为什么?
如果我打开@echo on
,我会看到这一点,这是没有意义的:
set /p BOOTSTRAPSERVERS="Bootstrap servers with port, separated by comma(by default localhost:9092): "
Bootstrap servers with port, separated by comma(by default localhost:9092): host1:9092,host2:9092,host3:9092
REM echo "host1:9092,host2:9092,host3:9092"
if "host1:9092,host2:9092,host3:9092" == "" set BOOTSTRAPSERVERS="localhost"
echo All the servers to connect:
All the servers to connect:
FOR /F "usebackq delims=," %i in (`echo host1:9092 host2:9092 host3:9092`) do (
echo %i
echo.
)
(
echo host1:9092
echo.
)
host1:9092
如果仔细观察,echo
将字符串从逗号分隔变为空格分隔,此时%bootstrapserver%
没有双引号
如果是双引号,则输出为:
"host1:9092
为什么?
有没有更好的方法用分隔符分割字符串?FOR/F的标记机制是以行为单位工作的。
每个输入行(行由换行符分隔)令牌由选项
delims
和tokens
构建
delims=…
定义如何将文本拆分为标记。tokens=…
定义要创建的令牌数量,第一个令牌存储在FOR参数变量中,下一个令牌按字母顺序存储在下一个参数字符中
在此示例中,令牌%%A%%B%%C用于存储1
,2
,3
FOR /F "tokens=1,2,3" %%A ("1 2 3 4 5") DO ...
在您的情况下,您可能希望为host:
和value
但是您当前只有一行,这不适用于/F 但是您可以用换行符
LF
替换每个,
,替换是用完成的!主持人:,=%%~L代码>
然后/F的将获得多行,如:
这些行可以用分隔符:
@echo off
setlocal EnableDelayedExpansion
set "hosts=host1:9092,host2:9092,host3:9092,host4:4711"
(set LF=^
%=empty line=%
)
FOR %%L in ("!LF!") DO (
FOR /F "tokens=1,2 delims=:" %%1 in ("!hosts:,=%%~L!") DO (
echo Host: %%1 Value: %%2
)
)
要按标准分隔符(空格、制表符、逗号)拆分字符串,可以使用普通的for
循环(no/f
):
输出:
host1:9092
host2:9092
host3:9092
注意set
命令的语法(这样引号就不会成为值的一部分)。同样的语法也适用于set/p
:set/p”var=Prompt:“
不,只需使用拆分就可以了,
因为9092是一个端口,稍后我将在服务器地址中包含它,如主机:端口
。我试图理解原始版本,但我不明白;关于set LF=…
part既不“!hosts:,=%%~L!”
part。虽然我大致理解了你的意思,set LF=^…
部分是<代码>!主持人:,=%%~L代码>部件使用了变量替换语法(请参见设置/?
)!变量名称:=
在第一个外部循环中,您是否尝试在空行中执行for循环?我不明白;我想我可以搜索一行;for/?
中的示例显示,它可以迭代文件中的行,并使用分隔符分割每一行以搜索单词,因此,为什么不能在一行中执行此操作。。。。?我的意思是,类似于(*.txt)do中的/r%G(for/f“tokens=*%H do(findstr/C:string/IMN%H))
好的,外部循环是一个hack。有必要将LF/linefeed设置为FOR参数。这对于以后在的搜索/替换表达式中将其用作%%~L
是必需的!主持人:,=%%~L代码>为什么要使用echo
毕竟,为什么不这样做:对于/F“delims=,”%I in(“%bootstrapserver%”)do echo(%I
?我认为在for/F
循环中执行echo
的cmd.exe
实例将,
视为令牌分隔符,并用空格替换它们……不,这不起作用;我得到host1:9092
问题是没有usebackq
我可以使用%var%”
来解析这个var字符串,但是我不知道我能得到多少个主机;所以我可以打印%I
,这是第一个,但是第二个,第三个是%J
,%K
,等等。啊..所以如果分隔符在空格之间,选项卡
和,
,我不需要来表示/f
?很好知道。没有尽管在for/?
中,这并不完全正确。for
和for/f
的工作方式完全不同。for/f
在行上循环,标记其字符串for
在列表的每个组件上循环。因此,带有单个字符串的for/f
只循环一次,for
在每个组件上循环一次(本例中为三次)。有关/?
或更多解释性文本,请参阅。(或在上运行echo,然后了解您自己)
set "bootstrapservers=host1:9092,host2:9092,host3:9092"
for %%a in (%bootstrapservers%) do echo %%a
host1:9092
host2:9092
host3:9092