如何在Shell脚本中将日期格式MM-DD-YY HH:MI AM/PM转换为YYYY-MM-DD



我目前正在尝试使用以下命令转换日期格式

while IFS=$'t' read -r -a ValArray
do
FILEDATE=${ValArray[0]}
COMPDATE=`date -d  $FILEDATE +'%Y-%m-%d'`

我在尝试从文件中动态获取值并将其与今天的日期进行比较时遇到以下错误

++ read -r -a ValArray
++ FILEDATE='02-11-20 2:25 AM'
+++ date -d 02-11-20 2:25 AM +%Y-%m-%d
date: extra operand `AM'
Try `date --help' for more information.

如何覆盖此项并获取YYYY-MM-DD格式的日期?

使用参数展开

POSIX shell提供参数扩展,从字符串的左(前(或右(后(开始的string中删除substring

${string#substring}     Strip shortest match of $substring from front of $string
${string##substring}    Strip longest match of $substring from front of $string
${string%substring}     Strip shortest match of $substring from back of $string
${string%%substring}    Strip longest match of $substring from back of $string

子字符串可以包含正常的文件globbing,例如'*''?'等。

在您的情况下(使用f='02-11-20 2:25 AM'(,您可以从左侧和右侧删除各种子字符串,以获得月份、日期和年份。然后,您可以将2位数的年份乘以100,得到4位数的年份,如下所示:

f='02-11-20 2:25 AM'
f="${f% *}"     # trim AM (to first space) from right (back)
f="${f% *}"     # trim 2:25 (to first space) from right
m="${f%%-*}"    # trim to last - from right leaving month
y="${f##*-}"    # trim to last - from left (front) leaving year
d="${f#*-}"     # trim to first - from left leaving day-year
d="${d%-*}"     # trim to first - from right leaving day
y=$((y*100))    # mulitply 2-digit year by 100
printf "%4d-%02d-%02dn" "$y" "$m" "$d"     # output in desired format

使用expr substr string start length

POSIX还提供了旧的expr ....字符串操作函数集,尽管由于涉及命令替换,它可能比内置的参数扩展慢。与此相关的是:

expr substr string start length

从索引(基于1(start开始的string中提取length字符子串。您可以使用检索月份、日期和年份

f='02-11-20 2:25 AM'
m=$(expr substr "$f" 1 2)                   # extract 2-digit substring at 1
d=$(expr substr "$f" 4 2)                   # extract 2-digit substring at 4
y=$(expr substr "$f" 7 2)                   # extract 2-digit substring at 7
y=$((y*100))                                # mulitply 2-digit year by 100
printf "%4d-%02d-%02dn" "$y" "$m" "$d"     # output in desired format

(注意:就像使用[...]时,使用expr ...时总是引用变量一样(

使用sed

您还可以使用带有三个捕获组和三个反向引用的基本sed替换,以正确的顺序重新插入日期组件。捕获组(text)捕获它们之间的文本(由正则表达式text表示(,并且在表达式的替换部分中,捕获的文本可以使用编号的后参考1(用于第一次捕获(、2(用于第二次捕获(等重新插入,例如

f='02-11-20 2:25 AM'
echo "$f" | sed 's/^(..)-(..)-(..).*$/300-1-2/'

示例输出

两种方法产生相同的输出:

2000-02-11

如果您还有其他问题,请告诉我。

最新更新