什么可以更快地替换此sed命令?

时间:2014-08-28 04:55:49

标签: perl unix sed

我有一个脚本,其中sed命令在输入文件上有效。

 sed -i 's/SESSION_ID/sid/g;s/TIME_HOUR/hh/g;s/TIME_MINUTE/mm/g;s/TIME_SECOND/ss/g;s/TIME_MILLISECOND/mss/g;s/MSISDN/MS/g;s/IMSI/IM/g;s/IMEISV/IV/g;s/name_ALLOCATED_UE_ADDRESS_IPV4/aI4/g;s/IPV6/I6/g;s/OPERATION_TYPE/OT/g;s/LOCATION_AREA_CODE/LC/g;s/CELL_IDENTITY/CI/g;s/RAT_TYPE/RT/g;s/APN/AP/g;s/COUNTRY_CODE/CC/g;s/NETWORK_CODE/NC/g;s/name_SGSN_ADDRESS_IPV4/sI4/g;s/QCI/QC/g;s/SUBSCRIBERGROUP/SG/g;s/MONITORING_KEY/MK/g;s/QUOTA_VOLUME_BIDIRECTIONAL/QV/g;s/MBR_UL/MU/g;s/MBR_DL/MD/g;s/RULE_ID/RD/g;' $FiletosqeezE

现在问题是......执行时间比预期的要多。你能告诉我这个sed命令更快的替换吗?我们甚至可以在这里接受perl的帮助.....谢谢。

3 个答案:

答案 0 :(得分:4)

使用命令行perl(将所有替换加入单个表达式):

perl -i -pe '
    BEGIN {
      %hash = qw(SESSION_ID sid TIME_HOUR hh TIME_MINUTE mm TIME_SECOND ss TIME_MILLISECOND mss MSISDN MS IMSI IM IMEISV IV name_ALLOCATED_UE_ADDRESS_IPV4 aI4 IPV6 I6 OPERATION_TYPE OT LOCATION_AREA_CODE LC CELL_IDENTITY CI RAT_TYPE RT APN AP COUNTRY_CODE CC NETWORK_CODE NC name_SGSN_ADDRESS_IPV4 sI4 QCI QC SUBSCRIBERGROUP SG MONITORING_KEY MK QUOTA_VOLUME_BIDIRECTIONAL QV MBR_UL MU MBR_DL MD RULE_ID RD);
      $pat = join "|", sort {length($b) <=> length($a)} keys %hash; 
    }
    s/\b($pat)\b/$hash{$1}/g;
  '  $FiletosqeezE

切换

  • -i:编辑<>个文件(如果提供了扩展程序,则进行备份)
  • -p:为输入文件中的每个“行”创建一个while(<>){...; print}循环。
  • -e:告诉perl在命令行上执行代码。

答案 1 :(得分:2)

如果您需要能够在每一行上实际 所有这些替换项,那么您至少不能使用sed本身,就不可能更快地完成任务。其他工具(例如awkperl)可能会为您提供改进。

如果您有可能利用您可能拥有的额外信息,有一些方法可以让它更好。

例如,如果您只希望每行上出现一个的每个字符串(例如SESSION_ID),则可以删除全局标记g,意味着它不会为每次更换而处理其余部分。

或者,如果每一行只包含一个关键字(例如,没有包含SESSION_ID TIME_HOUR的行,则可以使用awk之类的东西进行替换,并使用next,以便第一个替代品立即移动到下一行而不是检查所有其他行。

或者,如果您知道所有关键字都在该行的开头,则可以更改替代品:

s/SESSION_ID/sid/g

成:

s/^SESSION_ID/sid/

这可能会加快速度,因为它不必超越前几个角色。

但是,如果没有额外的信息,可能通过为此特定目的创建硬编码程序而不是将更通用的sed与脚本一起使用来提高性能。 / p>

通过这种方式,您可以调整每次读取调用加载了多少数据等内容。由于你的sed字符串是固定的而不是正则表达式,所以我不会期望太多有很大的改进,但如果你愿意放入,那么它可能值得一试。前期工作。


值得注意的是,sed命令在我的包装盒上在不到12秒的时间内通过100M源文件轻松过关,我也不会认为坏。

请确保无论您测试什么选项,都要正确测试它们。 测量,不要猜!

答案 2 :(得分:1)

根据着名的sed单行文字: http://sed.sourceforge.net/sed1line.txt

如果你修改这样的替换:

sed 's/something/changed/g;s/another/one/g' 

sed '/something/ s//changed/g; /another/ s//one/g' 

你得到了改进,我在一个小文件上进行了测试,系统部分减少了一半:

(precise)cronkilla@localhost:/tmp$ time sed 's/dog/cat/g;s/fox/horse/g;s/quick/slow/g;s/the/blah/g' n4.txt > n6.txt

real    0m0.043s
user    0m0.039s
sys 0m0.004s


(precise)cronkilla@localhost:/tmp$ time sed '/dog/ s//cat/g;/fox/ s//horse/g;/quick/ s//slow/g;/the/ s//blah/g' n4.txt > n6.txt
real    0m0.052s
user    0m0.050s
sys 0m0.002s