2014-08-28 48 views
0

我有一个脚本,其中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的帮助.....谢谢。

+0

你预计它会花多少时间?例如,除非您可以利用额外的信息,例如在行首之前的所有字符串,否则您不太可能使其速度更快。 – paxdiablo 2014-08-28 04:59:41

+0

对不起,如果我听起来很愚蠢......但并没有明确表达你的观点,例如“如线路起始处的所有字符串,例如”。 ....感谢您的回复BTW ... – Geetika 2014-08-28 05:06:17

+0

给出了一个输入样本,以便可以完成优化。你的sed动作列表对于所有那些“独立”模式的通用修改是快速的,但也许不是通用的(像1行上的许多术语或者在相反行中从不在同一行上,......) – NeronLeVelu 2014-08-28 05:44:27

回答

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在命令行上执行代码。
+0

我想这是值得投票的,它运行速度比我的100M测试文件中的sed'选项快两倍(尽管没有替换)。 – paxdiablo 2014-08-28 05:21:19

2

如果您需要能够真正做到所有每行的替代品,你不太可能能够使其更快,至少sed本身。其他工具(如awkperl)可能会为您提供改进。

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

例如,如果你只希望一个出现在每行每串(如SESSION_ID),你可以摆脱全球标志g,这将意味着它不会处理行的其余部分的每次更换。

或者,如果每一行永远只能包含一个关键字(例如,既SESSION_IDTIME_HOUR没有台词,你可以使用像awk做代,并使用next使得第一替补立即移动到下一行,而不是检查所有其他

或者,如果你知道所有的关键字是在该行的开始,你可以改变你的替代品:

s/SESSION_ID/sid/g 

到:

s/^SESSION_ID/sid/ 

这可能会加快速度,因为它不会有超越前几个字符。

但是,如果没有额外的信息,您可能会通过为此特定目的创建一个硬编码的程序而不是通过脚本使用更通用的sed来获得更快的性能。

因此,您可以调整每个读取调用的加载数据量等。我不希望因为你的sed字符串是固定的而不是正则表达式,所以这是一个很大的改进,但是如果你愿意投入前期工作,它可能是值得一试的。


对于它的价值,这sed命令,通过在我的箱子少于12秒的100M源文件轻盈,我不认为糟糕。

只要确保无论您测试的选项是否正确测试。 措施,不要猜测!

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)[email protected]:/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)[email protected]:/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 
+0

我想知道为什么是这样吗?为什么这个实现不会优化它呢? – 2014-08-28 06:26:57

+0

我不知道我没有看过sed源代码,但它看起来确实有优化的余地。 – 2014-08-28 06:32:54

+0

你的系统时间减半既没有统计学意义也没有用,顺便说一句。 CPU时间是用户+ sys,从原来的43时间到你版本中的52时间。然而,如前所述,一个样本大小对于得出结论几乎没有用处。 – paxdiablo 2014-08-28 06:37:33