bash将MMM-DD-YYYY变量转换为YYYY-MM-DD

bash将MMM-DD-YYYY变量转换为YYYY-MM-DD,bash,Bash,我在bash工作。我有以下变量: $dt=2018年6月16日 我需要将此值转换为日期格式YYYY-MM-DD。如何进行转换?我试过: dt_new=$(date –-date="$dt" +%F) …但是bash抛出错误消息 日期:时间格式非法 仅在bash中,您所要求的是不可能作为一行代码的。date命令的行为因操作系统而异。如果您希望可移植地使用此命令,则需要考虑不同的口味 #!/usr/bin/env bash function dateconv { local newdat

我在bash工作。我有以下变量:

$dt=2018年6月16日

我需要将此值转换为日期格式YYYY-MM-DD。如何进行转换?我试过:

dt_new=$(date –-date="$dt" +%F)
…但是bash抛出错误消息

日期:时间格式非法


仅在bash中,您所要求的是不可能作为一行代码的。
date
命令的行为因操作系统而异。如果您希望可移植地使用此命令,则需要考虑不同的口味

#!/usr/bin/env bash

function dateconv {
    local newdate
    case "$(uname -s)" in
      *BSD|Darwin)  newdate="$(date -jf '%b-%d-%Y' "$1" '+%F')" ;;
      Linux)        newdate="$(date -d "$1" '+%F')" ;;
      *)            echo "Can't convert this, sorry." >&2; exit 1 ;;
    esac
    echo "$newdate"
}

dateconv "${1:-$(date '+%b-%d-%Y')}"
但是,如果您想完全避免使用外部工具,可以使用稍微多一些的代码来假装:

#!/usr/bin/env bash

function dateconv {
    local m=(z Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec z)
    local year month day

    year="${1##*-}"

    for f in "${!m[@]}"; do
        if [ "${1%%-*}" = "${m[$f]}" ]; then
            month="$f"
            break
        fi
    done
    if [[ $f = "z" ]]; then
        echo "Invalid month: ${1%%-*}" >&2
        exit 1
    fi

    day="${1#*-}"
    day="${day%-*}"

    printf '%04d-%02d-%02d\n' "$year" "$month" "$day"
}

dateconv "${1:-$(date '+%b-%d-%Y')}"
第二种选择不太清晰,也不太灵活,但应该适用于Bash3或4、Linux或BSD/macOS环境

请注意,
%b
日期格式表示大写首字母


还请注意,上述解决方案采用您的主题(
MMM-DD-YYYY
)中所述的格式,而不是您的示例(
2018年6月16日
)。毫无疑问,您可以将其调整为实际使用的格式。

您可以使用-v选项执行此操作:

date -v $dt '+%Y-%m-%d
OSX终端中的结果:

2018-06-12

这将适用于任何GNU
日期

$ date -d'June-16-2018' +%Y-%m-%d
2018-06-16

漂亮的引号,
,而不是“普通”引号,
?抱歉。我在中复制了漂亮的引号。它们应该是普通引号。我刚刚更新了帖子。您如何分配给
dt
?分配中不能有空格(如您所示),并且您不能在左侧使用
$
$dt
在您调用
date
之前有什么内容?我实际上是通过一个带有一些清理工作的cat来分配dt。我正在运行filedate=$(cat“some_file.csv”| grep“date是:“{print$2}”sed's//-/g';sed's//,///g')我怎么能看到这个?没有关于手册页版本的信息是的,我也试过了。可能是因为我在使用osx?
date--version-date:非法选项--version
啊。所以你有一个特定于操作系统的date版本。我想是的。确保你的答案是清楚的。f…开头的那行对我来说看起来很奇怪。难道
不应该吗
成为一个
#
?@MarkSetchell-有多种方法可以处理这个问题。
${!m[@]}
扩展到数组的索引集,而
#
只提供计数。在这种情况下,我们知道总是只有12个月,我们可以使用
{1..12}
相反,但是用
处理这个问题显然是有教育意义的。:-(还要注意
$m
数组的第一个元素,以填充
0
索引。)