我遇到了日期命令的一个奇怪行为:
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')"