日期管道 - 错误还是我的错误?

日期管道 - 错误还是我的错误?

我遇到了日期命令的一个奇怪行为:

echo '1 JAN 2023' | LC_ALL=en_US.utf8  date -d -

这会产生明显错误的输出:

Sun Jun 11 12:00:00 AM CEST 2023

但这没关系:

LC_ALL=en_US.utf8  date -d '1 Jan 2023'  # Sun Jan  1 12:00:00 AM CET 2023

这也很好:

my_date='1 JAN 2023'
LC_ALL=en_US.utf8  date -d  "$my_date" # Sun Jan  1 12:00:00 AM CET 2023

我无法让管道版本工作。是 bug 还是我做错了什么?

答案1

date命令的--date/-d选项需要字符串参数- 标准输入被丢弃,并-根据 GNUdate命令的解析为日期输入字符串一般日期语法,其中表示

目前,后面没有数字的连字符将被忽略。

空字符串表示今天的开始(即午夜)。

因此您的命令实际上等同于LC_ALL=en_US.utf8 date -d 'today 00:00'

要从管道获取输入,您需要将 stdin 转换为参数 - 例如xargs

$ echo '1 JAN 2023' | LC_ALL=en_US.utf8  xargs -d '\n' date -d
Sun Jan  1 12:00:00 AM EST 2023

或者 (正如 Raffa 所建议的)通过将其传递给命令读取标准输入,捕获该命令的输出命令替换

$ echo '1 JAN 2023' | LC_ALL=en_US.utf8  date -d "$(cat -)"
Sun Jan  1 12:00:00 AM EST 2023

相反,使用-f选项要简单得多,它从标准输入读取:

$ echo '1 JAN 2023' | LC_ALL=en_US.utf8  date -f -
Sun Jan  1 12:00:00 AM EST 2023

man date

   -f, --file=DATEFILE
          like --date; once for each line of DATEFILE

答案2

我不知道date您使用的是哪个版本,但man date 没有提到何时-指定输入来自标准输入:

$ echo something | date -d -
Sun Jun 11 00:00:00 CEST 2023
$ date -d -
Sun Jun 11 00:00:00 CEST 2023

答案3

正如其他人提到的,date不从标准输入读取;该-d选项要求在下一个参数中输入日期字符串。您可以使用命令替换将命令的输出放在那里。

date -d "$(echo '1 JAN 2023')"

相关内容