![Board logo](images/default/logo.gif)
标题: [文本处理] 求批处理 提取文本中每行最末尾的中括号及其内部字符 [打印本页]
作者: anjohnlee 时间: 2014-10-15 10:07 标题: 求批处理 提取文本中每行最末尾的中括号及其内部字符
求大神动动手指啊。
我有几百万行格式基本固定的文本如下,每行末尾一定是一个中括号及内部字符。但是行中也可能出现中括号,现在我提取每行末尾那个中括号及其内部字符,行中中括号不要。
求大神写个批处理
> CT_875 [Chlamydia trachomatis D/UW-3/CX]
> superantigen-like protein [Staphylococcus aureus subsp. aureus str. Newman]
> tryptophanyl-tRNA [synthetase] [Salmonella enterica subsp. enterica serovar Agona str. SL483]
> AsnC [family transcriptional] regulator [Geodermatophilus obscurus DSM 43160]
> methionyl-tRNA formyltransferase [[Clostridium] saccharolyticum WM1]
作者: Batcher 时间: 2014-10-15 11:22
如果你确定行尾方括号内部没有嵌套方括号的话,可以试试这样:- sed "s/.*\(\[[^][]\+\]\)$/\1/" a.txt > b.txt
复制代码
作者: terse 时间: 2014-10-15 17:37
回复 1# anjohnlee
一楼数据最后行 最后结果是什么 “methionyl-tRNA formyltransferase [[Clostridium] saccharolyticum WM1]”
是希望得到 “[Clostridium] saccharolyticum WM1” 还是希望最后结果 ‘saccharolyticum WM1“
作者: Batcher 时间: 2014-10-15 19:32
回复 3# terse
楼主说最后一行是他弄错了。800万行,2楼代码耗时30分钟左右(他当时没有精确计时)。
作者: terse 时间: 2014-10-15 21:23
来个GAWK- gawk -F[ "{print FS$NF}" a.txt >b.txt
复制代码
作者: CrLf 时间: 2014-10-15 21:56
本帖最后由 CrLf 于 2014-10-15 23:20 编辑
实测用 grep 更快些,大概是支持双向预查的正则要比替换来得快捷:- grep -o -P "(?<=\[)[^\[\]]+?(?=][^\[\]]*$)" a.txt>b.txt
复制代码
测试 400 万行文本 31 秒,2 楼的 sed 方案是 77 秒,不知道楼主的测试背景是什么,为什么竟然要半个小时...
发现理解错了,楼主是要求保留括号的,那就是这样:- grep -o -P "\[[^\[\]]+\]$" a.txt>b.txt
复制代码
或者这样:- grep -o -e "\[[^]\[]\{1,\}\]$" a.txt>b.txt
复制代码
作者: DAIC 时间: 2014-10-15 23:15
来一个可以兼容一对嵌套方括号的- sed "s/.*\(\[[^][]*\[\+[^][]*\]\+[^][]*\]\)$/\1/" a.txt | sed "s/.*\(\[[^][]\+\]\)$/\1/"
复制代码
写的比较挫,有时间再想想如何优化。
作者: CrLf 时间: 2014-10-15 23:42
本帖最后由 CrLf 于 2014-10-15 23:43 编辑
用 powershell 来一个 .net 特色的正则,平衡组匹配最大的闭合 []:- type a.txt | %{
- if($_ -match '\[((?<test>\[)|(?<-test>\])|[^\[\]])*(?(test)(?!))\]$') {
- $matches[0]
- }
- }
复制代码
作者: xxpinqz 时间: 2014-10-16 14:56
来瞻仰下诸位大神。。。。
作者: terse 时间: 2014-10-16 19:37
本帖最后由 terse 于 2014-10-16 19:39 编辑
这里效率上还是SED略逊 grep 确实高
gwaK 直接分隔符 不处理嵌套 无嵌套的话和 grep 有一比
grep- grep -o -P "\[([^\[\]]|(?R))*\]" a.txt
复制代码
SED- sed -r "s/.*(\[([^][]+|\[[^][]+\])+\])$/\1/" a.txt
复制代码
作者: CrLf 时间: 2014-10-16 21:46
回复 10# terse
原来 perl 正则还有 (?R) 的用法,我特么一直以为平衡组是 .net 独有的,才知道 perl 也支持,不过是叫递归组
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |