我必须完成一项相对简单的任务,基本上我有大量具有以下格式的文件
“2014-01-27”,“07:20:38”,“数据”,“数据”,“数据”
基本上我想提取前两个字段,将它们转换为一个unix纪元日期,加上6个小时(由于时区差异),然后用生成的毫秒替换前两个原始列(unix epoch,自19700101起转换为工厂) 我写了一个工作正常的脚本,问题是非常非常慢,我需要运行150多个文件,总行数超过5.000.000,我想知道你是否对如何有任何建议我可以让它更快,这是:
#!/bin/bash
function format()
{
while read line; do
entire_date=$(echo ${line} | cut -d"," -f1-2);
trimmed_date=$(echo ${entire_date} | sed 's/"//g;s/,/ /g');
seconds=$(date -d "${trimmed_date} + 6 hours" +%s);
millis=$((${seconds} * 1000));
echo ${line} | sed "s/$entire_date/\"$millis\"/g" >> "output"
done < $*
}
format $*
答案 0 :(得分:3)
我试图避免外部命令(日期除外)以获得时间。测试显示它比您的代码快4倍。 (好吧,三人的perl解决方案比我快40倍!)
#! /bin/bash
function format()
{
while IFS=, read date0 date1 datas; do
date0="${date0//\"/}"
date1="${date1//\"/}"
seconds=$(date -d "$date0 $date1 + 6 hours" +%s)
echo "\"${seconds}000\",$datas"
done
}
output="output.txt"
# Process each file in argument
for file ; do
format < "$file"
done >| "$output"
exit 0
答案 1 :(得分:3)
您正在为每个输入行产生大量进程。通过快速浏览可能很容易将其中一半的因素考虑在内,但我肯定会建议改用Perl或Python。
perl -MDate::Parse -pe 'die "$0:$ARGV:$.: Unexpected input $_"
unless s/(?<=^")([^"]+)","([^"]+)(?=")/ (str2time("$1 $2")+6*3600)*1000 /e'
我想推荐Text::CSV,但我没有在这里安装它,如果你有要求在第二秒之后不接触字段,那么它可能不是你需要的。这很快,很脏,但可能比“适当的”CSV解决方案简单得多。
真正的肉是来自Date::Parse的str2time
函数,我想它会比重复调用date
快得多(ISTR它在内部做了一些记忆,所以它可以做附近的日期很快)。正则表达式用输出替换前两个字段;请注意/e
标志,该标志允许在替换部件中评估Perl代码。 (?<=^")
和(?=")
零宽度断言要求存在这些匹配,但在替换操作中不包括它们。 (我最初用附加的双引号代替,但是这个改变后,它们会被保留,因为显然你想保留它们。)
如果您希望脚本在出现错误的情况下继续(可能会将标准错误重定向到文件,那么将die
更改为warn
。
答案 2 :(得分:2)
在awk中使用存在函数mktime
,经过测试,它比perl更快。
awk '{t=$2 " " $4;gsub(/[-:]/," ",t);printf "\"%s\",%s\n",(mktime(t)+6*3600)*1000,substr($0,25)}' FS=\" OFS=\" file
这是测试结果。
$ wc -l file
1244 file
$ time awk '{t=$2 " " $4;gsub(/[-:]/," ",t);printf "\"%s\",%s\n",(mktime(t)+6*3600)*1000,substr($0,25)}' FS=\" OFS=\" file > /dev/null
real 0m0.172s
user 0m0.140s
sys 0m0.046s
$ time perl -MDate::Parse -pe 'die "$0:$ARGV:$.: Unexpected input $_"
unless s/(?<=^")([^"]+)","([^"]+)(?=")/ (str2time("$1 $2")+6*3600)*1000 /e' file > /dev/null
real 0m0.328s
user 0m0.218s
sys 0m0.124s