这两天就折腾一东西,如何替换一行里面的几个字符串。
因为数据比较大,又涉及到效率的问题。
假设只处理一个字符串
ffsddfrgggh ertijg335345348573489 598908908590-3-[][]459009 49568fsdfssd
想替换掉红色部分的字段为5个空格。假设红色字符串的位置分别为【20,25】,【45,50】
由于是文件就涉及到读文件的问题
1,最不理想做法
while read LINE
do str1=`echo "$LINE"|awk ' { print substr($LINE,1,19)}'`
str2=`echo "$LINE"|awk ' { print substr($LINE,26,18)}'` str3=`echo "$LINE"|awk ' { print substr($LINE,51)}'`
str=`echo "$str1 $str2 $str3"` echo "$str">>temp
done <$filename
|
上面的例子我用去测试1.5G的文件时候,跑了一个小时才处理了100M。最后受不了了直接Ctrl+C掉了
2,改进的做法
while read LINE
do
str=`echo "$LINE"|awk ' { printf"%s %s %s",substr($LINE,1,19),substr($LINE,26,18),substr($LINE,51)}'`
echo "$str">>temp
done <$filename
|
上面的例子就是改正了echo中的处理字符串而已。效果也是不好
3,学长就一直要求我看能不能用一个命令搞定。后面才发现主要瓶颈在于读文件上,上面的两个例子都是一行一行读,一个1.5G的文本文件具有上千万行的处理级别。
3,LINUX下的最终版
测试1.5G只用了4分钟。
cat filename | awk '{printf"%s %s %s\n",substr($0,1,19), substr($0,26,18),substr($0,51)}'>temp
|
总结:
其实这个虽然简单,但是涉及到awk 的substr()内置函数的用法,只有了解了为什么($0,26,18)后面最后一个数代表的是从26开始截取18个字符的意思才能作对。
还有AIX不支持内置变量如$LINE,所以因尽量转换为$1,$2的状态。
阅读(941) | 评论(0) | 转发(0) |