您的位置:首页 > 运维架构 > Shell

将文件内容逐行读取处理并写入对应文件中

2015-11-06 19:32 716 查看
场景:现有一个文件里面有大量的数据,约3.6G,4000多万行,每行的数据格式是一样的,共有9个域,如下:

3880961244329353 9 26 3862561814 2015-08-28 23:45:28 qinglei 2015-08-28 23:50:13

现在的需求是:将每一行数据按照倒数第二个域的日期来分类,相同日期的行写入相应日期的文件中,并且对文件名的日期进行处理(将”2015-08-28”修改为20150828,并以此命名文件名)

解决办法一

刚开始没有考虑到效率的问题,只是想实现它,所以写了比较笨的方法,如下:

history_line_all_count=`cat /data0/userreport/activeprocess/activeprocess.history.log | wc -l`
echo $history_line_all_count
for((i=1;i<=$history_line_all_count;i++));
do
date=`awk 'NR=='$i' {print $(NF-1)}' /data0/userreport/activeprocess/activeprocess.history.log`
date_e=`echo $date | sed 's/-//g'`
activeprocess="activeprocess.$date_e"
sed -n ''$i'p' /data0/userreport/activeprocess/activeprocess.history.log >> /usr/home/shixi_xiongchao1/activeprocess.history/$activeprocess
done


方法思路就是:首先先统计出文件的行数(history_line_all_count),然后使用for循环对每行进行处理,处理的方式是使用awk读取出指定行的倒数第二个域($(NF-1)),也就是日期,然后对日期使用sed处理,将”-“去掉,去掉后的日期组合成文件名(activeprocess),最后在用sed将此行读取出来并写入到组合好文件名的文件中

注:此种方法效率极低,对于数据量很大的文件来说根本不可行,运行了一夜,才分析出几百K的数据,所以没有办法,重新考虑优化,所以想出了下面一种方法

解决办法二

方法如下:

cat activeprocess.history.log | awk '{print $0 >> "activeprocess.history/activeprocess."$(NF-1) }'


没有看错,就是一个命令,直接使用awk,因为awk本身就是逐行读取内容的,所以就不用再for的,awk读取每一行的时候将倒数第二个域($(NF-1))组合为文件名,然后打印当前读取的行输入到文件中,但是这种方式的文件名中日期没有处理,所有在后面再统一对activeprocess.history目录下面的文件批量重命名

注:这种方法效率很快,3.6G的数据差不多一个小时就处理完了

下面附上之后对第二种方法解析出来的文件名批量重命名的方法:

#!/bin/sh
##批量重命名当前文件夹activeprocess.history下的文件名
##将文件名中的"-"去掉
##
for line in `ls activeprocess.201* | awk '{print $(NF)}'`
do
line_new=`echo $line | sed 's/-//g'`
echo $line_new
mv $line $line_new
done
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息