用awk求和的日期

时间:2018-12-03 18:12:56

标签: awk

我正在尝试使用awk在某日期中累计几天:

    $(window).load(function(){
        var placeholder = 'SOME TEXT\nSOME TEXT\n SOME TEXT';
        $('textarea.placeholder').attr('value', placeholder);

        $('textarea').focus(function(){
            if($(this).val() === placeholder){
                $(this).val('')
                .removeClass('placeholder');
                }
            });

        $('textarea').blur(function(){
            if($(this).val() ===''){
                $(this).val(placeholder)
               .addClass('placeholder');
                }    
            });
        });

但是我的回报是

awk 'BEGIN { print date -d $(date -d "20181222" "+%Y%m%d") + 30}'

我期待中

030

我的日期是一个字符串。

3 个答案:

答案 0 :(得分:4)

这很有趣地描述了为什么获得结果的原因。

在awk中,未加引号的单词(不是函数或命令)是变量:

awk 'BEGIN { print date -d $(date -d "20181222" "+%Y%m%d") + 30}'

在这里,您有两次“ date”变量,两次“ d”变量,2个带引号的字符串和一个数字文字。

由于尚未将变量“ date”和“ d”初始化,因此取决于上下文,它们将被视为空字符串或数字零。因为您在“日期”和“ d”之间使用-,所以将它们置于数字上下文中。

还请注意:

  • awk字符串污染是简单地将2个字符串并排放置:没有显式运算符
  • $符号可以描述为“字段值取消引用”运算符:$右侧的单词是要使用的字段编号。
  • 在BEGIN块中,awk尚未处理任何记录,因此任何$x将成为空字符串

awk本质上看到了这一点:

awk 'BEGIN { print date -d $(date -d "20181222" "+%Y%m%d") + 30}'
awk 'BEGIN { print (0 - 0) $((0 - 0) "20181222" "+%Y%m%d") + 30}'  # variable values
awk 'BEGIN { print 0 $(0 "20181222" "+%Y%m%d") + 30}'              # arithmetic
awk 'BEGIN { print 0 $("020181222+%Y%m%d") + 30}'                  # string concat
awk 'BEGIN { print 0 $(20181222) + 30}'                            # field is a number
awk 'BEGIN { print 0 "" + 30}'                                     # field value
awk 'BEGIN { print 0 (0 + 30)}'                                    # numeric context
awk 'BEGIN { print 0 30}'                                          # arithmetic
awk 'BEGIN { print "030"}'                                         # string concat

您可以在GNU awk中本地进行日期算术:请参阅https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html

gawk -v date=20181222 -v days=30 'BEGIN {
  datespec = substr(date, 1, 4) " " substr(date, 5, 2) " " (substr(date, 7, 2) + days) " 0 0 0"
  time = mktime(datespec)
  print strftime("%Y%m%d", time)
}'
20190121

幸运的是,GNU awk的日期时间库将“ 2018年12月52日”识别为“ 2019年1月21日”。


如果您没有GNU awk并且无法安装它,那么perl就足够了:

perl -sE '
    use Time::Piece;
    use Time::Seconds;
    $t = Time::Piece->strptime($date, "%Y%m%d");
    $t += $days * ONE_DAY;
    say $t->ymd("");          # or, say $t->strftime("%Y%m%d")
' -- -date=20181222 -days=30

答案 1 :(得分:1)

我不确定您为什么需要awk,好像您有GNU date,如果可以,请尝试执行一次。

date '+%Y%m%d' -d "20181222+30 days"
20190121

答案 2 :(得分:0)

您可以在awk内调用命令

$ awk -v d=30 'BEGIN{cmd="date -d \"20181222+" d "days\" +\"%Y%m%d\""; 
                     cmd | getline date; print "date:" date}'

date:20190121