我开发了下面的脚本来预处理文件我试图从文件的标题中提取时间戳,并根据时间戳的长度删除每行末尾的一些字符。删除后,它会将时间戳附加到文件中的每一行。这个脚本需要将近30分钟来处理一个4GB的文件。有什么方法可以提高性能吗?这个剧本写得更好吗?
if [ -f INPUT.TXT ]; then
echo "FILE exists."
date=$(cut -c8-25 INPUT.TXT | head -1)
date_format=$(echo $date | sed -e "s/./:/g")
echo -e " header date value is : $date"
echo -e "Header date value format is: $date_format"
leng_t=${#date_format}
len=`expr $leng_t + 1`
sed -i "s/.{${len}}$//" INPUT.TXT
sed -i s/$/$date_format/ INPUT.TXT
else
echo "FILE does not exist."
fi
- 主优化是通过将两个连续的
sed
组合为一个来获得的
相反:
使用:sed -i "s/.{${len}}$//" INPUT.TXT sed -i s/$/$date_format/ INPUT.TXT
这样可以将执行时间缩短两倍sed -i "s/.{$len}$/$date_format/" INPUT.TXT
此结果是显示所有后续优化增益的基本结果
所有后续优化都需要额外的磁盘空间来存储INPUT.TXT
文件的副本(即额外的4GB(:
- 尝试将结果放在一个单独的文件中,而不是将其编辑到位:
这样可以节省约10%的相对基本结果sed "s/.{$len}$/$date_format/" INPUT.TXT >INPUT.tmp.TXT mv -f INPUT.tmp.TXT INPUT.TXT
- 在多核机器上,这应该运行得更快:
这样可以节省约35%的相对基本结果rev INPUT.TXT | sed "s/^.{$len}//" | rev | sed "s/$/$date_format/" >INPUT.tmp.TXT mv -f INPUT.tmp.TXT INPUT.TXT
- 在多核机器上,如果替换中没有多字节字符(因为
cut
仍然无法处理(:
这样可以节省约50%的相对基本结果let cut_len=$len+1 rev INPUT.TXT | cut -c $cut_len- | rev | sed "s/$/$date_format/" >INPUT.tmp.TXT mv -f INPUT.tmp.TXT INPUT.TXT
因此,通过最佳优化,脚本的运行速度可以提高四倍
注意:所有测试都使用400MB文件完成。