Board logo

标题: [文本处理] 对findstr命令/g:开关的一点不解 [打印本页]

作者: wankoilz    时间: 2011-2-28 14:24     标题: 对findstr命令/g:开关的一点不解

代码:
  1. @echo off
  2. findstr /x /g:a.txt b.txt
  3. pause
复制代码
a.txt内容
  1. a
  2. b
  3. c
  4. d
复制代码
b.txt内容
  1. b
  2. b
  3. c
  4. d
复制代码

注意,a.txt和b.txt的最后一行都没有换行符。大家一看就知道这个代码的功能是从a.txt中逐一获取每行字符串然后在b.txt里面查找与之精确匹配的行。
问题来了:理想的结果应当是
  1. b
  2. b
  3. c
  4. d
复制代码
对吧?但是实际上的结果是
  1. b
  2. b
  3. c
复制代码
d不见了,这让人很意外...但是如果在b.txt最后一行加上换行符(a.txt最后加不加换行符都无所谓)就能得到理想的
  1. b
  2. b
  3. c
  4. d
复制代码
大家说说这是怎么回事?
作者: wc726842270    时间: 2011-2-28 16:19

我想是因为FINDSTR /X的原因吧,如果你去掉它就会得到想要的结果。
但是为什么加上/X,就会有这种效果呢?那么先看看这句话“ 打印完全匹配的行”
对这里是指“行”,什么能作为一行呢,我想就是两个换行符之间的内容吧。但是这时问题来了,在文件的开始和未尾并不一定有,我的认为是/X在文本的开始和结尾各加了个换行符。这个用法和FOR/F是一致的,可以先看下下面的例子
  1. setlocal enabledelayedexpansion
  2. for /f "delims=" %%a in ('ipconfig^|findstr /i "Address"') do set var=%%a
  3. set CarriageReturn=!var:~-1!
  4. 效果:变量CarriageReturn被赋值为一个回车符(0x0d,\r,Cr)
  5. 注释:源于 ipconfig 的输出每行行尾都有两个回车符,在被for /f截掉一个后还能剩一个;
  6.         引用时需要用变量延迟的形式,否则就会在预处理中被当做行结束符而被过滤掉
复制代码
是不是想到些什么呢,我想就是我上面所说的吧。另外FOR/F读取文本时是以计算机语言读取的(这里我也不知道是16还是2进制,必竟还没有学到那里,但我估计是16)
如有兴趣不防试一下,将一个小写的"d "(后有空格.但不包括引号)保存在文件中(格式默认就行),再打开看一下是不是乱码,如果是再用FOR/F解释一下,是不是原来的内容出来了.
以上都是个人的理解,希望对你有帮助
作者: wc726842270    时间: 2011-2-28 16:31

不好意思,有点没有注意到,就是"注释:源于 ipconfig 的输出每行行尾都有两个回车符"
这句话,在看看他给的例子时,发现是取的是最后一行,有兴趣的话不防试一下中间的.(在这里我估计是习贯问题,如果是我取完后一行后,删除它,之后再作相同的处理)
作者: wankoilz    时间: 2011-2-28 22:31

非常感谢wc726842270 的回复。去掉/x开关就OK了,这也给我了一点启发。
但是,findstr不也是以行为单位进行匹配的吗?
要是如你所说/x在文本开头和结尾加上换行符的话,就不应该出现“不理想”的结果啊...
还有,
将一个小写的"d "(后有空格.但不包括引号)保存在文件中(格式默认就行),再打开看一下是不是乱码
我这里不是乱码...
总之现在我还是只知道加上/x得不到理想结果,不加可以得到,但是原因还是不清楚,希望有兴趣的朋友一起思考下!

[ 本帖最后由 wankoilz 于 2011-2-28 22:39 编辑 ]
作者: wc726842270    时间: 2011-2-28 23:36     标题: 回复 4楼 的帖子

不好意思,我在2L的观点却实是有误,FINDSTR是以行为单位进行匹配的。
/X的的作用是“完全匹配”。但是如果没有打印出来,也就是说没有完全匹配。可以说在预处理时加了些东西。在经过实验后发现在b.txt后加个回车后即可显示出来,(两个文本最后都有回车也可以,但是只在a.txt后加回车确依然是原来的情况)。也就是说在预处理时。在a.txt的最后加了个回车。a.txt最后有了回车。而b.txt确没有,这也许就是为什么没有显示的原因了吧(以上是个人的理解)
另外可能是FINDSTR在最后的行中加了个回车(现在想想在文本开始加,也没什么意义),而且是离它最近的文件。
在文本中虽然有些符号看不见,但是在也是存在的,(用计算机的语言就可以理解了),如果有兴趣可以在某行加个空格再试试
作者: wankoilz    时间: 2011-3-1 10:52

感谢wc726842270参与讨论。
我想了很久也不能得出让自己信服的答案...很郁闷!
但是下面这个例或许能给人一点启发:
  1. @echo off&setlocal enabledelayedexpansion
  2. set s=^
  3. findstr /n "!s!" a.txt
  4. pause
复制代码
a.txt的内容
  1. a
  2. a
复制代码
a.txt里面有4行,三个换行符(最后一行没有换行符)。代码中变量!s!包含一个换行符,代码执行结果是
  1. 1:a
  2. 2:
  3. 3:
复制代码
打印出了包含换行符的3行,也就说findstr是可以匹配换行符的,但是....在加上/X开关后,就什么都得不到,但我还是不知道顶出现顶楼那种情况的原因....希望大家都来讨论下!

[ 本帖最后由 wankoilz 于 2011-3-1 10:56 编辑 ]
作者: wankoilz    时间: 2011-3-2 12:38

我自己顶一下...!




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2