Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 向文本文件中的所有时间戳添加小时数_Shell_Date_Awk_Sed - Fatal编程技术网

Shell 向文本文件中的所有时间戳添加小时数

Shell 向文本文件中的所有时间戳添加小时数,shell,date,awk,sed,Shell,Date,Awk,Sed,我有以下文本文件(file.dat): 我的目标是在这个文本文件中的每个时间戳('YYYY-MM-DD HH:MM:SS')上增加7个小时 所需的输出如下: random text 2019-10-11 03:22:33.456000^ text random 2019-12-01 06:45:56.789000 random 2019-11-12 04:22:33.456000 random stuffs,2019-11-01 06:45:56.789000 random, random 20

我有以下文本文件(
file.dat
):

我的目标是在这个文本文件中的每个时间戳('YYYY-MM-DD HH:MM:SS')上增加7个小时

所需的输出如下:

random text 2019-10-11 03:22:33.456000^ text random 2019-12-01 06:45:56.789000 random
2019-11-12 04:22:33.456000 random stuffs,2019-11-01 06:45:56.789000
random, random 2019-10-11 03:22:33.456000^ text everywhere 2020-01-01 06:45:56.789000
awk '{ip=$0;while(match(ip,/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]/,a)){ cmd="date +\"%F %T\" -d \"" a[0] " 7 hours \""; cmd | getline b; close(cmd); sub(a[0],b$0);ip=substr(ip,RSTART+RLENGTH)}; print $0}' file.dat
我目前有一个解决方案,但是对于一个只有10000行的文本文件,它需要1分钟的时间。我目前的做法如下:

random text 2019-10-11 03:22:33.456000^ text random 2019-12-01 06:45:56.789000 random
2019-11-12 04:22:33.456000 random stuffs,2019-11-01 06:45:56.789000
random, random 2019-10-11 03:22:33.456000^ text everywhere 2020-01-01 06:45:56.789000
awk '{ip=$0;while(match(ip,/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]/,a)){ cmd="date +\"%F %T\" -d \"" a[0] " 7 hours \""; cmd | getline b; close(cmd); sub(a[0],b$0);ip=substr(ip,RSTART+RLENGTH)}; print $0}' file.dat
这需要花费太多的时间,因为我的文本文件最多可以有1000000行。此外,我还没有检查,但我认为那里的
sub
函数可能会导致问题

因此,我一直在尝试寻找其他选择:

  • 使用
    sed

    sed "s#([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})#$(date -d '\1' +'%F %T')#g" file.dat
    
    当然,它不起作用,给出了一个错误
    无效日期\\1'
    。这并不奇怪,因为我不希望back引用在内部工作

  • 使用
    awk

    awk '{print gensub(/([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9]) ([0-9][0-9]):([0-9][0-9]):([0-9][0-9])/,strftime("%Y-%m-%d %H:%M:%S",mktime("\\1 \\2 \\3 \\4 \\5 \\6")),"g",$0)}' file.dat
    
    我对这个有希望,但结果是错误的:

    random text 1970-01-01 06:59:59.456000^ text random 1970-01-01 06:59:59.789000 random
    1970-01-01 06:59:59.456000 random stuffs,1970-01-01 06:59:59.789000
    random, random 1970-01-01 06:59:59.456000^ text everywhere 1970-01-01 06:59:59.789000
    
    所有的时间戳都变成了1970-01-01 06:59:59,这基本上意味着
    mktime
    返回了
    -1


  • 还有其他选择吗?任何有效的方法(使用bash)都可以。

    请尝试以下方法

    awk '
    {
      line=$0
      while(match($0,/[0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+/)){
         val=substr($0,RSTART,RLENGTH)
         split(val,array,"[- :.]")
         var=mktime(array[1] " " array[2] " " array[3] " " array[4] " " array[5]" " array[6])+(3600*7)
         new_val=strftime("%Y-%m-%d %H:%M:%S",var)
         $0=substr($0,RSTART+RLENGTH)
         sub(val,new_val,line)
         delete array
         val=var=new_val=""
      }
      print line
      line=""
    }
    '  Input_file
    
    输出如下

    random text 2019-10-11 03:22:33.456000^ text random 2019-12-01 06:45:56.789000 random
    2019-11-12 04:22:33.456000 random stuffs,2019-11-01 06:45:56.789000
    random, random 2019-10-11 03:22:33.456000^ text everywhere 2020-01-01 06:45:56.789000
    
    解释:添加上述代码的详细解释。请向右滚动查看说明:)


    时间戳格式不是固定的吗?这意味着一些在日期和时间之间有空格,而一些在日期和时间之间有逗号。整个文本文件中的所有时间戳都是“yyy-MM-DD HH:MM:SS”(日期和时间之间有空格)。我选择省略毫秒,因为将小时添加到时间戳时它将保持不变。第二行中的表达式
    2019-11-11,21:22:33.456000
    如何?它包含逗号而不是空格。顺便说一句,您正在从
    awk
    脚本中多次将
    date
    命令作为子进程发送,这将是一个瓶颈。通过使用
    mktime()
    strftime()。对不起,那是个打字错误。2.我已经在第二种方式中使用了mktime和strftime,但不起作用,但我还没有尝试替换当前工作解决方案中的日期。我试试看。谢谢:)