设想:
我正在将文件中的日期值提取到变量中,默认情况下它采用 DD-MM-YYYY 格式。我必须从系统日期中减去这个日期。如果我的两个日期都采用 DD-MM-YYYY 格式,则减法会给出错误的结果。因此,我在谷歌上阅读了一些内容,并决定将两个日期的格式设置为 YYYY-MM-DD,因为这将在减法后给出正确的值。我已成功将系统日期格式化为 YYYY-MM-DD,但很难将从文件中获取的日期转换为 YYYY-MM-DD 格式。
以下解决方案适用于单位数字日期:
$ date -d $(sed "s/-/\//g" <<< '9-2-1832') +%Y-%m-%d
Output : 1832-09-02
但是当我尝试将日期转换为两位数时,如下所示:
$ date -d $(sed "s/-/\//g" <<< '19-07-2021') +%Y-%m-%d
我得到输出
Invalid date '19/07/2021'
在哪里:
19 - is Date of a month
07 - is Month i.e. July in this case.
2021 - is Year
所需的输出为 ->2021-07-19
我正在 RH Linux 上工作,日期版本为:date (GNU coreutils) 8.22
请帮忙提供上述问题的解决方案。
答案1
对于您的情况,awk
可能是更好的方法:
$ awk -F'-' '{printf("%04d-%02d-%02d\n",$3,$2,$1)}' <<< '19-07-2021'
2021-07-19
答案2
您可以切换到 busybox date
,它允许指定输入格式:
$ date=19-7-2021
$ busybox date -D %d-%m-%Y -d "$date" +%F
2021-07-19
019-007-2021
(例如,请注意它不接受日期)。
与 ast-open 实现相同date
(不太可能在 RedHat 系统上开箱即用):
$ date -p %d-%m-%Y -d "$date" +%F
2021-07-19
如果您使用的是 BSD 而不是 GNU 系统,您会这样做:
$ date -jf %d-%m-%Y -- "$date" +%F
2021-07-19
或者您可以切换到zsh
而不是按bash
原样具有内置的日期解析和格式化:
$ zmodload zsh/datetime
$ strftime -rs t %d-%m-%Y $date && strftime %F $t
2021-07-19
(strftime
是可以访问标准strftime()
和strptime()
(带有-r
)API 的内置函数)。
它还具有适当的分割运算符和 a printf
,可以按任意顺序接受参数(使用%n$...
大多数printf()
实现中的语法,包括 GNU printf()
,但不是printf
内置的bash
,也不是 GNUprintf
独立实用程序),并且它不会将带有前导零的数字视为默认八进制:
$ printf '%3$04d-%2$02d-%1$01d\n' ${(s[-])date}
2021-07-19
或者使用匿名函数:
$ (){ printf '%04d-%02d-%02d\n' $3 $2 $1; } ${(s[-])date}
2021-07-19
或者这里,数组反转运算符:
$ printf '%04d-%02d-%02d\n' ${(s[-]Oa)date}
2021-07-19
答案3
如果格式硬编码为DD-YY-YYYY
,您还可以硬编码整个表达式并使用子串提取重新格式化,速度非常快:
#!/bin/bash
dmy=$(date +%d-%m-%Y)
ymd="${dmy: -4}-${dmy:3:2}-${dmy:0:2}"
echo "$dmy -> $ymd"
如果格式是D[D]-M[M]-YYYY
你可以使用常用表达重新格式化,这有点慢:
#!/bin/bash
dmy="9-2-1932"
if [[ "$dmy" =~ ^([[:digit:]]+)-([[:digit:]]+)-([[:digit:]]+)$ ]] ; then
ymd="${BASH_REMATCH[3]}-${BASH_REMATCH[2]}-${BASH_REMATCH[1]}"
fi
echo "$dmy -> $ymd"
您可以使用以下格式更好一点printf
:
dmy="9-02-2032"
if [[ "$dmy" =~ ^([[:digit:]]+)-([[:digit:]]+)-([[:digit:]]+)$ ]] ; then
printf -v ymd '%.4d-%.2d-%.2d' \
"${BASH_REMATCH[3]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[1]}"
fi
echo "$dmy -> $ymd"
这个答案的前一个版本证明我没有完全阅读它,转换YYYY-MM-DD
为DD-MM-YYYY
:
#!/bin/bash
ymd=$(date +%Y-%m-%d)
dmy="${ymd: -2}-${ymd:5:2}-${ymd:0:4}"
echo "$ymd -> $dmy"
答案4
仅使用 sed 的快速而精益的解决方案:
echo 19-07-2021 | sed -E 's/^([0-9]{1,2})-([0-9]{1,2})-([0-9]{4})$/\3-\2-\1/'