我想使用以下行处理200 GB的文件:
...
{"captureTime": "1534303617.738","ua": "..."}
...
目标是将此文件拆分为按小时分组的多个文件。
这是我的基本脚本:
#!/bin/sh
echo "Splitting files"
echo "Total lines"
sed -n '$=' $1
echo "First Date"
head -n1 $1 | jq '.captureTime' | xargs -i date -d '@{}' '+%Y%m%d%H'
echo "Last Date"
tail -n1 $1 | jq '.captureTime' | xargs -i date -d '@{}' '+%Y%m%d%H'
while read p; do
date=$(echo "$p" | sed 's/{"captureTime": "//' | sed 's/","ua":.*//' | xargs -i date -d '@{}' '+%Y%m%d%H')
echo $p >> split.$date
done <$1
一些事实:
jq
不能正常工作,因为某些JSON行无效。您能帮助我优化此bash脚本吗?
谢谢
答案 0 :(得分:3)
这个awk解决方案可能会助您一臂之力:
awk -F'"' '{file=strftime("%Y%m%d%H",$4); print >> file; close(file) }' $1
它实际上替代了您的while
循环。
此外,您可以将完整的脚本替换为:
# Start AWK file
BEGIN{ FS='"' }
(NR==1){tmin=tmax=$4}
($4 > tmax) { tmax = $4 }
($4 < tmin) { tmin = $4 }
{ file="split."strftime("%Y%m%d%H",$4); print >> file; close(file) }
END {
print "Total lines processed: ", NR
print "First date: "strftime("%Y%m%d%H",tmin)
print "Last date: "strftime("%Y%m%d%H",tmax)
}
随后您可以运行为:
awk -f <awk_file.awk> <jq-file>
注意:strftime
的使用表明您需要使用GNU awk。
答案 1 :(得分:2)
您可以通过更改此选项开始优化
sed 's/{"captureTime": "//' | sed 's/","ua":.*//'
有了这个
sed -nE 's/(\{"captureTime": ")([0-9\.]+)(.*)/\2/p'
-n
禁止自动打印图案空间
-E
在脚本中使用扩展的正则表达式