|
namejm
荣誉版主
       batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
    『楼 主』:
[共同讨论]for语句读取文本内容的一些陷阱
使用 LLM 解释/回答一下
1、普通for语句会忽略以分号开头的文本:
test.txt内容:
;abc
ai
::te
,te st
test
测试代码:
@echo off
for /f "delims=" %%i in (test.txt) do echo %%i
pause
此陷阱在不用for的 type test.txt、more test.txt和findstr .* test.txt 语句中不存在。
2、在for语句中使用带 tokens=1* delims=: 的 findstr /n .* test.txt 的时候,会过滤掉行首的所有冒号:
test.txt同1;
测试代码:
@echo off
for /f "tokens=1* delims=:" %%i in ('findstr /n .* test.txt') do echo %%j
pause
解决问题1和问题2的通用方案:
稍微复杂一点的:
@echo off
for /f "delims=" %%i in ('findstr /n .* test.txt') do (
set "str=%%i"
call set "str=%%str:*:=%%"
call echo "%%str%%"
)
pause
最简洁的 (经测试,这个方案不具备通用性,因为"delims= eol=" 会把行首为引号的内容过滤掉,看来真是前门驱虎后门进狼、引号和分号不能兼顾啊):
@echo off
for /f "delims= eol=" %%i in (test.txt) do echo %%i
pause
简洁方案中的"delims= eol=" 顺序不能颠倒,否则会出现偏差。
不知道强大的 for 还会有哪些陷阱会让不明就里的我们往里跳,请各位收集一下,以便日后编写代码的时候能少走弯路。
Last edited by namejm on 2007-5-17 at 09:17 PM ]
### 1、Ordinary for statements ignore text starting with a semicolon:
Content of test.txt:
;abc
ai
::te
,te st
test
Test code:
@echo off
for /f "delims=" %%i in (test.txt) do echo %%i
pause
This trap does not exist in the statements of type test.txt, more test.txt, and findstr .* test.txt without using for.
### 2、When using findstr /n .* test.txt with tokens=1* delims=: in the for statement, all colons at the beginning of the line will be filtered:
test.txt is the same as 1;
Test code:
@echo off
for /f "tokens=1* delims=:" %%i in ('findstr /n .* test.txt') do echo %%j
pause
General solutions to solve problem 1 and problem 2:
A little more complicated one:
@echo off
for /f "delims=" %%i in ('findstr /n .* test.txt') do (
set "str=%%i"
call set "str=%%str:*:=%%"
call echo "%%str%%"
)
pause
The most concise one (After testing, this solution is not universal, because "delims= eol=" will filter out the content with quotes at the beginning of the line. It seems that it is really driving the tiger away from the front door and letting the wolf in from the back door. Quotes and semicolons cannot be taken into account):
@echo off
for /f "delims= eol=" %%i in (test.txt) do echo %%i
pause
In the concise solution, the order of "delims= eol=" cannot be reversed, otherwise deviations will occur.
I don't know what other traps the powerful for will have that will make us jump in without knowing, please everyone collect them so that we can take fewer detours when writing code in the future.
Last edited by namejm on 2007-5-17 at 09:17 PM ]
此帖被 +15 点积分 点击查看详情 评分人:【 ccwan 】 | 分数: +15 | 时间:2007-1-25 05:39 |
|
|

尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-1-25 05:33 |
|
|
9527
银牌会员
     努力做坏人
积分 1185
发帖 438
注册 2006-8-28 来自 北京
状态 离线
|
『第 2 楼』:
使用 LLM 解释/回答一下
首先我想说的是FOR语句默认是忽略以“分号”开头的行,而不是冒号。
其次for /f "eol= delims=" %%a in (xxx) do command 命令中不会忽略任何符号开头的行,也就是说会显示全部的内容........
First of all, what I want to say is that the FOR statement ignores lines starting with "semicolons" by default, not colons.
Secondly, in the command "for /f "eol= delims=" %%a in (xxx) do command", no lines starting with any symbol are ignored, that is to say, all contents will be displayed........
|

我今后在论坛的目标就是做个超级坏人!!! |
|
2007-1-25 05:42 |
|
|
lzmyst
新手上路

积分 19
发帖 10
注册 2005-12-13
状态 离线
|
『第 3 楼』:
使用 LLM 解释/回答一下
几乎所有教程都说delims要放在最后,今天才知道也是有陷阱的。
Almost all tutorials say that delims should be placed at the end. I just found out today that there are also traps.
|
|
2007-1-25 05:46 |
|
|
pengfei
银牌会员
    
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第 4 楼』:
使用 LLM 解释/回答一下
又一个值得注意的地方, 不能说是陷阱, 任何程序自然不能顾及所有方面, 这就得靠我们平时多留意了.
Another thing to note, it can't be called a trap, any program naturally can't take all aspects into account, this is where we need to pay more attention in our daily lives.
|

业精于勤而荒于嬉,形成于思而毁于随。 |
|
2007-1-25 05:51 |
|
|
namejm
荣誉版主
       batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『第 5 楼』:
使用 LLM 解释/回答一下
Originally posted by 9527 at 2007-1-24 16:42:
首先我想说的是FOR语句默认是忽略以“分号”开头的行,而不是冒号。
呵呵,多谢提醒,笔误已经修正。
其次for /f "eol= delims=" %%a in (xxx) do command 命令中不会忽略任何符号开头的行,也就是说会显示全部的内容........
这个方案会忽略掉以空格打头的行,兄弟测试一下就知道了。
Originally posted by pengfei at 2007-1-24 16:51:
又一个值得注意的地方, 不能说是陷阱, 任何程序自然不能顾及所有方面, 这就得靠我们平时多留意了.
这些值得注意的地方,在微软的使用手册里没有任何地方提及,究竟是它刻意忽略的bug还是问题太小而不屑于提及异或是没有察觉到,已经无从得知,但是从使用者的角度来说,有bug的地方却没有正式的说明,无异于是一个个隐藏着的陷阱等着别人往里跳^_^
Last edited by namejm on 2007-1-24 at 05:59 PM ]
Originally posted by 9527 at 2007-1-24 16:42:
First of all, I want to say that the FOR statement by default ignores lines starting with a semicolon, not a colon.
Hehe, thanks for the reminder, the typo has been corrected.
Secondly, in the command "for /f "eol= delims=" %%a in (xxx) do command", no lines starting with any symbol will be ignored, that is, all contents will be displayed...
This solution will ignore lines starting with spaces. Brother, just test it and you'll know.
Originally posted by pengfei at 2007-1-24 16:51:
Another point worth noting, it can't be said to be a trap. Any program naturally can't take into account all aspects, and this is where we need to pay more attention in our daily lives.
These points worth noting are not mentioned anywhere in Microsoft's user manual. Whether it's a bug it deliberately ignores, a problem too small to mention, or it hasn't noticed, it's impossible to know. But from the user's perspective, there are bugs with no formal explanation, which are like hidden traps waiting for others to fall into ^_^
Last edited by namejm on 2007-1-24 at 05:59 PM ]
|

尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-1-25 05:54 |
|
|
vkill
金牌会员
     
积分 4103
发帖 1744
注册 2006-1-20 来自 甘肃.临泽
状态 离线
|
『第 6 楼』:
使用 LLM 解释/回答一下
"delims= eol=" 顺序不能颠倒
for /?上不是这样的啊
"delims= eol=" order cannot be reversed
It's not like that in for /?
|
|
2007-1-25 08:22 |
|
|
namejm
荣誉版主
       batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『第 7 楼』:
使用 LLM 解释/回答一下
哈哈,for /? 里还说:eol=c -指一个行注释字符的结尾(就一个) 。我狂吐血ing——嘿嘿,实际上是过滤掉以 c 打头的行,不知是哪个家伙翻译的,E文也太差了点吧?
言归正传,我所说的顺序不能颠倒,并不是指所有的情形,而是说为了能同时处理以分号和冒号打头的行内容,这个顺序不能颠倒。
Hehe, the /? in for also says: eol=c - refers to the end of a line comment character (just one). I'm really angry - heh, actually it filters out lines starting with c. I don't know which guy did the translation, his English is too bad.
Let's get back to the main point. What I said about the order not being reversible doesn't refer to all situations, but rather that in order to handle line contents starting with semicolons and colons simultaneously, this order can't be reversed.
|

尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-1-25 08:31 |
|
|
vkill
金牌会员
     
积分 4103
发帖 1744
注册 2006-1-20 来自 甘肃.临泽
状态 离线
|
『第 8 楼』:
使用 LLM 解释/回答一下
Originally posted by namejm at 2007-1-25 08:31:
哈哈,for /? 里还说:eol=c -指一个行注释字符的结尾(就一个) 。我狂吐血ing——嘿嘿,实际上是过滤掉以 c 打头的行,不知是哪个家伙翻译的,E ...
汗,才发现for /?有这么大个超级错误,狂晕中
Originally posted by namejm at 2007-1-25 08:31:
Haha, the /? for for also says: eol=c - refers to the end of a line comment character (just one). I'm really frustrated. - Hehe, actually it filters out lines starting with c. I don't know which guy did the translation, E...
Sweat, just realized there's such a big super error in for /?, really dizzy
|
|
2007-1-25 08:43 |
|
|
pengfei
银牌会员
    
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第 9 楼』:
使用 LLM 解释/回答一下
for /f "eol= delims=" %%i in (test.txt) do echo %%i "eol= delims=" 不能颠倒, 本机测试没有发现错误.
看来for /?的注释真的有点问题啊.
eol=c - 指一个行注释字符的结尾(就一个)
delims=xxx - 指分隔符集。这个替换了空格和跳格键的
默认分隔符集。
上面的说明我们在理解时产生了歧义, eol是过滤与行首字符匹配的行. 就像delims默认的分隔符为空格或TAB. 而eol的默认过滤的行首字符为;号, 而for /?却没有说明.
namejm兄说明给出的解决代码, for /f "delims= eol=" %%i in (test.txt) do echo %%i 它的作用和"delims=" 一样是取消默认空格作为分隔符, 而"eol="是取消;作分隔符.
下面代码为过滤行首为冒号的行, 同时取消了默认的分号分隔符.
@echo off
for /f "delims= eol=: " %%i in (test.txt) do echo %%i
pause
test.txt
abc
:123
4:56
;
;def
::
dok:cto:::
elo分隔符只能为一个, 上面代码故意让elo有两个分隔符, 可是只过滤了行首为:号的行, 而空格行却没有过滤.
for /f "eol= delims=" %%i in (test.txt) do echo %%i "eol= delims=" cannot be reversed, and no errors were found in local testing.
It seems that the comments in for /? are really a bit problematic.
eol=c - refers to the end of a line comment character (just one)
delims=xxx - refers to the delimiter set. This replaces the default delimiter set of spaces and tabs
default delimiter set.
There is ambiguity in our understanding of the above description. eol filters lines whose first character matches. Just like the default delimiter of delims is space or TAB. And the default first character of eol to filter is the ; character, but for /? does not explain.
Brother namejm's explanation gives the solution code, for /f "delims= eol=" %%i in (test.txt) do echo %%i Its function is the same as "delims=" to cancel the default space as a delimiter, and "eol=" to cancel the ; as a delimiter.
The following code is to filter lines whose first character is a colon, and cancel the default semicolon delimiter.
@echo off
for /f "delims= eol=: " %%i in (test.txt) do echo %%i
pause
test.txt
abc
:123
4:56
;
;def
::
dok:cto:::
The eol delimiter can only be one. The above code deliberately has two delimiters in elo, but only filters lines whose first character is :, and blank lines are not filtered.
|

业精于勤而荒于嬉,形成于思而毁于随。 |
|
2007-1-25 09:24 |
|
|
hxmupdata
初级用户
 
积分 76
发帖 39
注册 2007-3-9
状态 离线
|
『第 10 楼』:
使用 LLM 解释/回答一下
看个帖要花半个小时,,,不愧是经典帖..............................
It takes half an hour to read a post... It really is a classic post..............................
|

狐狸喜欢狡猾。。 |
|
2007-3-14 22:30 |
|
|
wudixin96
银牌会员
    
积分 1928
发帖 931
注册 2007-1-6
状态 离线
|
『第 11 楼』:
使用 LLM 解释/回答一下
下面代码为过滤行首为冒号的行, 同时取消了默认的分号分隔符.
CODE:
--------------------------------------------------------------------------------
@echo off
for /f "delims= eol=: " %%i in (test.txt) do echo %%i
pause
应该是
下面代码为过滤行首为冒号的行, 同时取消了默认的空格和跳格键分隔符.
The following code filters lines starting with a colon and cancels the default space and tab delimiters.
CODE:
--------------------------------------------------------------------------------
@echo off
for /f "delims= eol=: " %%i in (test.txt) do echo %%i
pause
It should be
The following code filters lines starting with a colon and cancels the default space and tab delimiters.
|
|
2007-4-4 01:07 |
|
|
ccuu668
初级用户
 
积分 57
发帖 29
注册 2006-12-27
状态 离线
|
『第 12 楼』:
使用 LLM 解释/回答一下
看来只有多多学习学习基础的东西了.看的不彻底.
It seems that I can only study basic things more. I didn't understand thoroughly.
|
|
2007-5-2 15:32 |
|
|
luowei14
初级用户
 
积分 193
发帖 98
注册 2007-1-17
状态 离线
|
『第 13 楼』:
使用 LLM 解释/回答一下
。。。呵。。microsoft还有这个BUG啊。。。晕晕
...Hehe. Microsoft still has this bug... Oh my
|

这家伙很聪明 什么都没留下 |
|
2007-8-15 17:27 |
|
|
knoppix7
银牌会员
    
积分 1287
发帖 634
注册 2007-5-2 来自 cmd.exe
状态 离线
|
『第 14 楼』:
使用 LLM 解释/回答一下
set /?里的BUG更多。。。
There are more bugs in set /?...
|
|
2007-8-15 22:04 |
|
|
dai13910
新手上路

积分 10
发帖 5
注册 2007-12-27
状态 离线
|
『第 15 楼』:
使用 LLM 解释/回答一下
恩!很多细节值得推敲
Well! Many details are worth pondering
|
|
2008-1-11 14:39 |
|