找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 41640|回复: 10

[文本处理] 求批处理 提取文本中每行最末尾的中括号及其内部字符

[复制链接]
发表于 2014-10-15 10:07:24 | 显示全部楼层 |阅读模式
求大神动动手指啊。
我有几百万行格式基本固定的文本如下,每行末尾一定是一个中括号及内部字符。但是行中也可能出现中括号,现在我提取每行末尾那个中括号及其内部字符,行中中括号不要。
求大神写个批处理
>  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]
发表于 2014-10-15 11:22:57 | 显示全部楼层
如果你确定行尾方括号内部没有嵌套方括号的话,可以试试这样:
  1. sed "s/.*\(\[[^][]\+\]\)$/\1/" a.txt > b.txt
复制代码
发表于 2014-10-15 17:37:41 | 显示全部楼层
回复 1# anjohnlee
一楼数据最后行 最后结果是什么 “methionyl-tRNA formyltransferase [[Clostridium] saccharolyticum WM1]”
是希望得到  “[Clostridium] saccharolyticum WM1”    还是希望最后结果  ‘saccharolyticum WM1“
发表于 2014-10-15 19:32:56 | 显示全部楼层
回复 3# terse


    楼主说最后一行是他弄错了。800万行,2楼代码耗时30分钟左右(他当时没有精确计时)。
发表于 2014-10-15 21:23:31 | 显示全部楼层
来个GAWK
  1. gawk -F[ "{print FS$NF}" a.txt >b.txt
复制代码
发表于 2014-10-15 21:56:34 | 显示全部楼层
本帖最后由 CrLf 于 2014-10-15 23:20 编辑

实测用 grep 更快些,大概是支持双向预查的正则要比替换来得快捷:
  1. grep -o -P "(?<=\[)[^\[\]]+?(?=][^\[\]]*$)" a.txt>b.txt
复制代码
测试 400 万行文本 31 秒,2 楼的 sed 方案是 77 秒,不知道楼主的测试背景是什么,为什么竟然要半个小时...
发现理解错了,楼主是要求保留括号的,那就是这样:
  1. grep -o -P "\[[^\[\]]+\]$" a.txt>b.txt
复制代码
或者这样:
  1. grep -o -e "\[[^]\[]\{1,\}\]$" a.txt>b.txt
复制代码
发表于 2014-10-15 23:15:57 | 显示全部楼层
来一个可以兼容一对嵌套方括号的
  1. sed "s/.*\(\[[^][]*\[\+[^][]*\]\+[^][]*\]\)$/\1/" a.txt | sed "s/.*\(\[[^][]\+\]\)$/\1/"
复制代码
写的比较挫,有时间再想想如何优化。
发表于 2014-10-15 23:42:31 | 显示全部楼层
本帖最后由 CrLf 于 2014-10-15 23:43 编辑

用 powershell 来一个 .net 特色的正则,平衡组匹配最大的闭合 []:
  1. type a.txt | %{
  2.    if($_ -match '\[((?<test>\[)|(?<-test>\])|[^\[\]])*(?(test)(?!))\]$') {
  3.       $matches[0]
  4.    }
  5. }
复制代码
发表于 2014-10-16 14:56:31 | 显示全部楼层
来瞻仰下诸位大神。。。。
发表于 2014-10-16 19:37:56 | 显示全部楼层
本帖最后由 terse 于 2014-10-16 19:39 编辑

这里效率上还是SED略逊 grep 确实高
gwaK 直接分隔符 不处理嵌套 无嵌套的话和 grep 有一比
  
grep
  1. grep -o -P "\[([^\[\]]|(?R))*\]" a.txt
复制代码
SED
  1. sed -r "s/.*(\[([^][]+|\[[^][]+\])+\])$/\1/" a.txt
复制代码

评分

参与人数 1技术 +1 收起 理由
CrLf + 1 递归匹配

查看全部评分

发表于 2014-10-16 21:46:44 | 显示全部楼层
回复 10# terse


    原来 perl 正则还有 (?R) 的用法,我特么一直以为平衡组是 .net 独有的,才知道 perl 也支持,不过是叫递归组
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-20 23:29 , Processed in 0.042590 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表