我有一个脚本,其中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 :(得分: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
本身,就不可能更快地完成任务。其他工具(例如awk
和perl
)可能会为您提供改进。
如果您有可能利用您可能拥有的额外信息,有一些方法可以让它更好。
例如,如果您只希望每行上出现一个的每个字符串(例如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