[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] 【已解决】findstr命令表达补集错误?

本帖最后由 bluewing009 于 2011-11-23 22:38 编辑

解决6楼

1.我想在1.txt文本里找到 不含 pause和echo 的显示行(显示行就是echo 没有>),就是:不含 pause和 echo且没有>的 行
我是这么写的:findstr /v "echo.*[^^^>] pause" 1.txt
结果错误
2.我尝试补集的写法findstr echo.*[^^^>] 1.txt
结果是:echo行和echo >行

问题:[^]不是补集么?应该是不含有补集内的元素,为什么2中都输出了
我如果想达到开头所说的目的如何写呢?

举例
  1. echo 000
  2. echo 3234
  3. pause
  4. djkllls
  5. dfsdk
  6. echo asdas>11.txt
  7. echo asdas>>11.txt
复制代码


变成
  1. djkllls
  2. dfsdk
  3. echo asdas>11.txt
  4. echo asdas>>11.txt
复制代码


例子中echo 行没有>排除了
1

评分人数

    • CrLf: 感谢给帖子标题标注[已解决]字样PB + 2

我水平不行,这说的只可以试试,别当真了...
[] 里当然可以用补集,但不需要转义  [>] 和[^>] 但需要引号括起来
发生错误的原因,除了以为要转义外,主要是逻辑上有误,比如查的是 echo.*[^>] 那方括内不允许有“>”难道 “>” 不能包含在 .* 里么? 因此想要表达不允许有 > 符,必须把 .* 的 . 换成不允许有>才行,如果是加/v排除的写上要排除的那部分就行,没加/v 而用补集排除,那就得全匹配才能排除——不知我表达清楚没有
附上用于本题的命令还不知我理解题意没有,应该有点参考价值吧
  1. findstr/v "echo[^>]*[>] pause" 1.txt
复制代码
1

评分人数

    • CrLf: 乐于助人技术 + 1

TOP

标题

回复 2# yyykkkyyyy


    /v  echo[^>]*[>]的结果是显示echo 不包含>的行,与我的题意正好相反,但是我反推/v  echo[^>]*[^>]应该是显示不包含“echo 没有>的”,结果所有echo都不显示……

TOP

然后我这样findstr echo[^>]*应该是显示echo且没有>的行吧?结果都显示了

TOP

本帖最后由 bluewing009 于 2011-11-22 23:23 编辑

奇怪的是如果直接写findstr [^>]*[^>] 按照理解应该显示“没有>”的行,结果除了开头为>没显示,其他都显示了,也包括行中间含有>

不明白……
还有findstr .*[^>]应该显示所有行尾不是>的行……但是也显示了……

TOP

回复 5# bluewing009

如果说我那句是正好相反,则把 /v 去掉就行了,我确实没明白你的题意,要不就是这个意思:
  1. findstr/v "echo[^>]*$ pause" 1.txt
复制代码
总之, 你还是逻辑没理清,我这把有echo 不带 > 的和有echo 带 > 的两者选一都有例句了

TOP

  1. grep -E -v "pause|echo.*>|>.*echo" a.txt
复制代码
1

评分人数

    • CrLf: 乐于助人PB + 5

TOP

本帖最后由 bluewing009 于 2011-11-23 10:27 编辑

回复 6# yyykkkyyyy


    那就分条说
1.有一个文本,各种命令都有
2.其中echo命令的行可分为有>和没有>的两种情况
3.需要显示除echo外的命令,以及echo行中含有>的行
4.换句话说,就是把echo的单独行(只有echo没有>)剔除出去
这样说明白了么?

另:如果去掉v就变成findstr "echo[^>]*[>] pause" 1.txt
这句话就是:找到echo且有>的和pause的行……

TOP

回复 7# awk


    额…………主要是findstr一般表达式运用不是很清楚……特别是补集
总是选不出希望的结果

TOP

回复 9# bluewing009


    我都无话可说,如果说结果承认但想不通为什么我还可以解释。
把我6楼用代码贴出来的你测试的情况描述一下总可以吧?

TOP

  1. findstr /v "^>echo echo.*>.* pause" 1.txt
复制代码
这样子行么?你们说的表示看不懂

TOP

  1. @echo off
  2. ::不含 pause和 echo且没有>的 行,就是没有pause、echo、>的行。
  3. findstr /lv "pause echo >" 1.txt
  4. pause
复制代码
1

评分人数

    • CrLf: 乐于助人PB + 5

TOP

回复 10# yyykkkyyyy


   初步测试可以。先谢谢你解决问题~  但是不是很明白原理.....
findstr/v "echo[^>]*$ pause" 1.txt
.        通配符: 任何字符
*        重复: 以前字符或类别出现零或零以上次数
^        行位置: 行的开始
$        行位置: 行的终点
[class]  字符类别: 任何在字符集中的字符
[^class] 补字符类别: 任何不在字符集中的字符        

这句话我奇怪为什么$,这个“行的终点”怎么讲?
我自己写的  findstr/v "echo[^>]*[>][^>]*  pause" 1.txt  我以为:
排除 (/v)echo行中间没有>重复,然后有> 的行
因为格式
echo dasdasds>1.txt
规律
echo 中间重复 > 其他不是>的字符  
所以我照着搬下来 findstr/v "echo[^>]*[>][^>]*
但是结果为
  1. djkllls
  2. dfsdk   
复制代码

为何呢?

TOP

本帖最后由 bluewing009 于 2011-11-23 20:10 编辑

回复 12# Hello123World


    这句话把所有echo 都打死了   thanks anyway

findstr /lv "pause echo >" 1.txt
这就排除了 含pause 行 含echo 行 含>行
而我需要的是 排除echo 且没有>的行......

6L可行

TOP

回复 13# bluewing009


    结果是对的才说明我理解题意对了,现帮你解释一下 echo[^>]*$ 可能多半的意思都懂,我讲得浅别介意,说得不对请各位高手指正。
都知道 . 表任意字符,那么[^>] 就表示除 > 之外的任意字符了
* 表示前一字符的 0 次或任意次重复,(注意是两者合作用,就是说不加 * 前面字符肯定会有,加了* 则也可以前字符1次也没有)
$ 表行结尾
那么 .*$ 表示的一直到行尾可以是任意字符——等于什么也没限制
那么 [^>]*$ 就是一直到行尾,是除了 > 之外的任意字符,换句话说,一直到行尾不允许有 > 符
如果不加 $ 呢?也就是你自己写的,那表示的一行里的某部分匹配就行了,虽然前面限制不要 > 符,但后面再有 > 符还是符合条件的,所以用
[^>]*$ 表示延续限制,可以没有字符了,也可以有多少字符都行,但不允许有 > 符
所以 echo[^>]*$ 就是表示自出现echo开始,一直到行尾不允许有 > 符
也就是匹配的是 echo 后不带 > 符的,如果也要求前面不带呢,^[^>]*echo[^>]*$
(当然也可用/b /e /x 等匹配参数代)
这说的是匹配,那么前面有参数/v 当然正好是排除这种情况了
相信整句不会再有疑问了吧

TOP

返回列表