Board logo

标题: [文本处理] [已解决]批处理怎样判断文本第五列数据并根据条件删除整行? [打印本页]

作者: xslxslxsl    时间: 2011-6-29 14:36     标题: [已解决]批处理怎样判断文本第五列数据并根据条件删除整行?

现有一个文件夹中有多个已ABC开头的文本文件(ABC1.TXT,ABC2.TXT......),文本的结构相同,下面数据中的空格实际上系TAB键,以tab键分隔数据
内容见附件
将第四个空后的数据进行比较,也就是第四个TAB见后的内容机型判断,若为9或7或没内容,则将整行删除,留下的数据另存
处理后的文本情况见附件
(即对文本数据中的第五列数据进行判断,若为9或为7或无内容就将此行删除)
用sed如何操作,用gawk又如何实现呢,或者有没有其它更加方便的做法,这样的文本数据有上千个之多,用哪个更加方便可靠,谢谢高手们指点。
高手们,sed 处理上千个几k到几十M这样结构的文本会不会吃力哦?若吃力,那如何优化比较好呢?谢谢各位高手告知。
各位高手再次请教:
. 表示匹配任意一个字符;.*表示匹配任意多个字符(1或多个),还是零个或多个啊?
作者: CrLf    时间: 2011-6-29 15:09

楼主上次不是问过了吗!
http://bbs.bathome.net/viewthread.php?tid=12947&highlight=
作者: xslxslxsl    时间: 2011-6-29 15:12

上次没有问清楚,麻烦大家再帮我解答一下,谢谢
作者: tmplinshi    时间: 2011-6-29 15:21

本帖最后由 tmplinshi 于 2011-6-29 23:14 编辑
  1. sed -i "/^.*\t.*\t.*\t.*\t[79]\?\t/d" *.txt
复制代码

作者: xslxslxsl    时间: 2011-6-29 15:32

若我要判断的内容不是一个字符而是两个呢?比如 9改为59,7改为67那该怎么写呢?若是空字符没有内容呢?麻烦耐心指导,我也是刚学,谢谢大家。
作者: tmplinshi    时间: 2011-6-29 16:43

本帖最后由 tmplinshi 于 2011-6-30 09:36 编辑

删除第五列是“59”或“67”或空字符的行:
  1. sed -i -r "/\t.*\t.*\t.*\t59|67\t/d; /\t.*\t.*\t.*\t\t/d" *.txt
复制代码
=============

删除第五列是“59”或“67”或“b”或“a”或“t”的行:
  1. sed -i -r "/\t.*\t.*\t.*\t59|67\t/d; /\t.*\t.*\t.*\t[bat]\t/d" *.txt
复制代码
=============

删除第五列是“59”或“67”或“b”或“a”或“t”或空字符的行:
  1. sed -i -r "/\t.*\t.*\t.*\t59|67\t/d; /\t.*\t.*\t.*\t[bat]?\t/d" *.txt
复制代码
=============

删除第五列是“59”或“67”或“b”或“a”或“t”或空字符的行:
  1. sed -i -r "/^.*\t.*\t.*\t.*\t(59|67|[bat])?\t/d" *.txt
复制代码

作者: xslxslxsl    时间: 2011-6-29 17:23

非常感谢,先谢谢,回去好好学习领悟一下,谢谢大家,特别要谢谢tmplinshi 的大力支持与耐心指导。
作者: xslxslxsl    时间: 2011-6-29 22:55

本帖最后由 xslxslxsl 于 2011-6-29 23:21 编辑

高手们,sed 处理上千个几k到几十M这样结构的文本会不会吃力哦?若吃力,那如何优化比较好呢?谢谢各位高手告知。
各位高手再次请教:
. 表示匹配任意一个字符;.*表示匹配任意多个字符(1或多个),还是零个或多个啊?
作者: xslxslxsl    时间: 2011-6-29 23:29

sed -i -r "/^.*……这个-r为什么要写啊,不写可以吗?"/^"也必须要写吗?向我这个文本中每行就五个TAB键固定死就行了,不用写"/^"是不是也可以哦,比如sed -i  ".*\t.*\t.*\t.*\t59|67\t/d" *.txt
作者: tmplinshi    时间: 2011-6-29 23:33

本帖最后由 tmplinshi 于 2011-6-29 23:40 编辑

8# xslxslxsl

改进了 6 楼的代码,改成了:

删除第五列是“59”或“67”或“b”或“a”或“t”或空字符的行:
  1. sed -i -r "/^.*\t.*\t.*\t.*\t(59|67|[bat])?\t/d" *.txt
复制代码


.      表示任意一个字符。
*     表示前一个字符出现 0 次,或 0 次以上。
\?    表示前一个字符出现 0 次,或 1 次。
-r    使用了这个参数后,可以省略一些斜杠。如 \? 就写成 ?,\| 就写成 |。
       假如上面的代码不使用 -r 参数,代码应该写为:
           sed -i "/^.*\t.*\t.*\t.*\t\(59\|67\|[bat]\)\?\t/d" *.txt
-i     直接修改文件。
作者: xslxslxsl    时间: 2011-6-29 23:52

本帖最后由 xslxslxsl 于 2011-6-30 00:00 编辑

10# tmplinshi
谢谢版主的耐心指点,我还是有点不清楚,向你说
.      表示任意一个字符
*     表示前一个字符出现 0 次,或 0 次以上
那.*是表示0 次或 0 次以上,还是1 次或1 次以上呢,
.      表示任意一个字符,这任意一个字符可以是空字符吗,也就是什么都没有吗?
sed 处理上千个几k到几十M这样结构的文本会不会吃力哦?若吃力,那如何优化比较好呢?
还有就是我还想看看你之前写的一条一条一条的三条代码,也就是用,(逗号)分开写成一行的,可惜被你编辑了,我没有及时保存下来,刚才我还在学习,没想到版主及时给答复完善更新了,麻烦再分开写一遍哦,打扰了。
再次感谢你哦。
作者: tmplinshi    时间: 2011-6-30 09:47

本帖最后由 tmplinshi 于 2011-6-30 13:09 编辑

11# xslxslxsl


那三条代码加回去了。
================================
.      表示 1 个任意字符。不表示空字符。
.*    表示 0 个,或 0 个以上任意字符。
================================
fr 删除第五列是“59”或“67”或“b”或“a”或“t”或空字符的行:
  1. fr *.txt -r:"^.*\t.*\t.*\t.*\t(59|67|[bat])?\t.*\n?" -t
复制代码
(\n 后面的 ?,是为了避免最后一行没有换行。)

强烈推荐 fr!我刚才测试了一千个文件,fr 用了 2 秒,sed (4.14) 用了 27 秒。以下是用 timieit 计算的结果:
Average for #fr.bat key over 1 runs

Version Number:   Windows NT 5.1 (Build 2600)
Exit Time:        8:00 am, Monday, January 1 1601
Elapsed Time:     0:00:02.187
Process Time:     0:00:00.078
System Calls:     19314
Context Switches: 8589
Page Faults:      3166
Bytes Read:       4853881
Bytes Written:    847969
Bytes Other:      158000


Average for #sed.bat key over 1 runs

Version Number:   Windows NT 5.1 (Build 2600)
Exit Time:        8:00 am, Monday, January 1 1601
Elapsed Time:     0:00:27.484
Process Time:     0:00:00.093
System Calls:     810124
Context Switches: 34826
Page Faults:      6223
Bytes Read:       5148897
Bytes Written:    11314757
Bytes Other:      3662156

作者: xslxslxsl    时间: 2011-6-30 11:02

非常感谢版主tmplinshi 的帮助,真的非常感谢,这样耐心的为我解答,给予我非常大的帮助,看在版主这样热心的帮助上,我也要好好将这些知识点学习好,真的很感谢,让我学习BAT的积极性又大增了。现在满脑子里就是惊喜和感谢。呵呵,看来我之后又要学习FR了哦,望版主tmplinshi 及大家能继续大力支持和耐心帮助我。再次感谢,感谢tmplinshi ,感谢大家。
作者: xslxslxsl    时间: 2011-7-5 00:18

本帖最后由 xslxslxsl 于 2011-7-5 16:22 编辑

12# tmplinshi
如果我这些数据不止六列,也就是大于等于六列,每行的长度又不一,还是按照之前的要求删除第五列符合条件的行,请问版主那代码如何写?因为.*中可能包括零个或多个\t。麻烦高手解答,谢谢!
作者: xslxslxsl    时间: 2011-8-15 11:16

回复 12# tmplinshi
版主,若我想将删除行的内容剪切或者复制出去,并将剪切或复制出去的行文本内容另存为新的文本,请我改如何操作,哪个参数可以实现,望赐教。谢谢!




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