I'm trying to add up days in a date using awk this way:
awk 'BEGIN { print date -d $(date -d "20181222" "+%Y%m%d") + 30}'
But my return is
030
I was expecting
20190121
The date I have is a string.
This is interesting to describe why you get the result you get.
In awk, an unquoted word (that is not a function or command) is a variable:
awk 'BEGIN { print date -d $(date -d "20181222" "+%Y%m%d") + 30}'
Here, you have the "date" variable twice, the "d" variable twice, 2 quoted strings and a numeric literal.
Since "date" and "d" as variables have not been initialized, they are treated as either the empty string or as the number zero, depending on the context. Because you use -
between "date" and "d", you are putting them into a numeric context.
Also note that:
$
symbol can be described as a "field-value dereferencing" operator: the word on the right-hand side of $
is the field number to use.$x
will become the empty stringawk essentially sees this:
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
You can do date arithmetic natively in GNU awk: see 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
Fortunately, GNU awk's datetime library recognises "December 52nd, 2018" as "January 21st, 2019"
If you don't have GNU awk and can't install it, perl should suffice:
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