【发布时间】:2019-01-11 17:38:27
【问题描述】:
TLDR 版本
如何优化以下脚本以更快地处理大文件。
-
./Processed/Ranked_endpoints_*.csv大约 ~1200 行 -
Dates.csv大约 100 万行
正在运行的 shell 脚本(我认为?它仍在运行...):
for RFGAUGE in ./Processed/Ranked_endpoints_*.csv
do
echo "Processing: $RFGAUGE"
mkIndex="$(basename $RFGAUGE)"
echo "$mkIndex"
##Duplicate the dates file to be able to edit it in place later on
cp Dates.csv Timed_${mkIndex%.*}.csv
##Remove header
tail -n +2 $RFGAUGE > noHead_${mkIndex%.*}.csv
##The slow part, go line by line and find if the time matches an event and copy to additional columns
while read LINE
do
##Asign variables from columns and replace , with space
read RankDUR RankRF RankPEAK RankAVG END START <<< `echo $LINE | cut -d, -f9,10,11,13,14,15 | sed 's/,/ /g'`
##Tried using sed and line numbers, failed
#STARTLINE=`grep -nr $START Dates.csv | cut -d: -f1`
#ENDLINE=`grep -nr $END Dates.csv | cut -d: -f1`
##Gawk only so can edit file in place
##Assigning AWK variables from UNIX variables
gawk -i inplace -v start="$START" -v end="$END" -v rankdur="$RankDUR" -v rankrf="$RankRF" -v rankpeak="$RankPEAK" -v rankavg="$RankAVG" 'BEGIN{FS=OFS=","}{if($2>=start && $2<=end) print $0,rankdur,rankrf,rankpeak,rankavg; else print $0}' Timed_${mkIndex%.*}.csv
done < noHead_${mkIndex%.*}.csv
rm noHead_${mkIndex%.*}.csv
done
加长版
我正在尝试根据几个仪表对最严重的降雨事件进行排名。数据的问题是降雨事件不会在完全相同的时间开始/停止,并且通常相对于彼此偏移几个小时。
我已经编写了一个脚本,该脚本从每个仪表的多年数据中提取了可以称为“事件”的内容,然后对事件的不同参数进行排名。我目前拥有的示例:
./Processed/Ranked_endpoints_*.csv
Date,D,M,Y,WOY, Duration (h),Total RF (mm),Max RF (mm),Rank Duration,Rank Total RF,Rank Max RF,AVG Rank,Rank AVG,EndTime EPOCH, StartTime EPOCH
04/12/2010 05:15:00,4,11,2010,48,7.0,22.599999999999994,8.2,71,39,12,40.6667,1,1291439700,1291414500
17/12/2004 08:00:00,17,11,2004,50,6.5,32.6,5.0,89,12,40,47,2,1103270400,1103247000
25/08/2010 18:00:00,25,7,2010,34,6.5,28.6,4.8,83,20,46,49.6667,3,1282759200,1282735800
...
上述 CSV 中的重要列是:
- 第 9、10、11、13 列 - 不同参数的排名
- 第 14 列 - 自纪元以来事件的结束时间(以秒为单位)
- 第 15 列 - 自纪元以来事件的开始时间(以秒为单位)
我还创建了一个 15 分钟的日期/时间 csv,其中包含自纪元以来的日期和时间,这类似于我用来提取“事件”数据的格式:
Dates.csv
...
03/12/2010 21:45:00,1291412700
03/12/2010 22:00:00,1291413600
03/12/2010 22:15:00,1291414500
03/12/2010 22:30:00,1291415400
03/12/2010 22:45:00,1291416300
03/12/2010 23:00:00,1291417200
03/12/2010 23:15:00,1291418100
03/12/2010 23:30:00,1291419000
03/12/2010 23:45:00,1291419900
04/12/2010 00:00:00,1291420800
04/12/2010 00:15:00,1291421700
04/12/2010 00:30:00,1291422600
04/12/2010 00:45:00,1291423500
04/12/2010 01:00:00,1291424400
04/12/2010 01:15:00,1291425300
04/12/2010 01:30:00,1291426200
04/12/2010 01:45:00,1291427100
04/12/2010 02:00:00,1291428000
04/12/2010 02:15:00,1291428900
04/12/2010 02:30:00,1291429800
04/12/2010 02:45:00,1291430700
04/12/2010 03:00:00,1291431600
04/12/2010 03:15:00,1291432500
04/12/2010 03:30:00,1291433400
04/12/2010 03:45:00,1291434300
04/12/2010 04:00:00,1291435200
04/12/2010 04:15:00,1291436100
04/12/2010 04:30:00,1291437000
04/12/2010 04:45:00,1291437900
04/12/2010 05:00:00,1291438800
04/12/2010 05:15:00,1291439700
04/12/2010 05:30:00,1291440600
...
考虑到我有大约 20 年的每个仪表 15 分钟的数据,并且可能有大量仪表。如果时间与“事件”之一匹配,将 9、10、11、13 列转移到 Dates.csv 的最佳方法是什么?上面的当前脚本不会将不同的仪表连接到 1 个 CSV 中,但通过剪切/粘贴很容易做到这一点。
因此,假设雨在 1 号后一小时到达 2 号并且持续时间少于 1 小时,那么最终输出将类似于以下内容:
03/12/2010 22:00:00,1291413600
03/12/2010 22:15:00,1291414500 ,71,39,12,1
03/12/2010 22:30:00,1291415400 ,71,39,12,1
03/12/2010 22:45:00,1291416300 ,71,39,12,1
03/12/2010 23:00:00,1291417200 ,71,39,12,1
03/12/2010 23:15:00,1291418100 ,71,39,12,1,13,25,35,4
03/12/2010 23:30:00,1291419000 ,71,39,12,1,13,25,35,4
...
04/12/2010 05:00:00,1291438800 ,71,39,12,1,13,25,35,4
04/12/2010 05:15:00,1291439700 ,71,39,12,1,13,25,35,4
04/12/2010 05:30:00,1291440600
【问题讨论】:
-
阅读
while IFS=, read var1 var2 var3 ... ; do .... ; done < inputFile。但我希望这可以归结为 1 个 awk 脚本来处理它们。现在不能花时间在上面。祝你好运。 -
您想要的输出是一个 CSV 文件还是几个文件(每个
Ranked_endpoints_*.csv一个)? -
我有一个不同的方法给你。为什么不使用 awk 处理 Ranked_endpoints* 以生成您需要的行,并调整时间到正确的 bin?将时间格式化为 YYYYMMDDhhmmss 并将这些行附加到单个文件中。一旦你有了那个大文件,按数字排序,你就会对所有的事件进行排序。如果您需要填写空白,您可以在大文件上额外执行一次,而不是像 csv 文件中的行一样多地执行。
-
我不明白如何从该输入中获取该输出。如果答案是“您不能”,那么请修复您的数据,以便样本输出正是您希望从样本输入中产生的结果。
-
Columns 7-10 are just from another gauge (2nd) and have been pasted into the output of gauge 1 using cut -d, -f 3-6。我不知道那是什么意思。提问时,只需发布从输入生成的输出,以便帮助展示您的问题,这样我们就可以针对您的输入测试潜在的解决方案,如果它完全产生您的输出,那么我们知道它有效,否则无效。让我们保持简单和轻松。
标签: bash performance csv optimization awk