我在解决这个问题时遇到了问题。我想将日期格式“YYYY-MM-DD”转换为“YYYYmmdd”(即2011-10-04
- > 20111004
)。
date -d 2011-03-19 +"%Y%m%d"
在命令行中工作,但不在while循环脚本中工作。
while循环的结果: 以下产生:
2011-03-17
date: invalid date `+%Y%m%d'
2011-03-10
date: invalid date `+%Y%m%d'
2010-07-07
date: invalid date `+%Y%m%d'
test.txt
包含以下示例行:
"2014-09-08T01:49:31Z"
"2014-01-30T03:41:41Z"
"2012-05-23T16:08:45Z"
"2012-05-04T10:16:04Z"
"2012-04-05T15:27:40Z"
#!/bin/bash
while read QUERYDATE
do
echo $QUERYDATE | sed 's/"\|T.*//g'
echo $(date -d $QUERYDATE_CONVERT +"%Y%m%d")
done < test.txt
答案 0 :(得分:2)
问题是永远不会定义QUERYDATE_CONVERT
。
替换:
echo $QUERYDATE | sed 's/"\|T.*//g'
使用:
QUERYDATE_CONVERT=$(echo $QUERYDATE | sed 's/"\|T.*//g')
这将导致输出:
20140908
20140130
20120523
20120504
20120405
考虑命令:
date -d $QUERYDATE_CONVERT +"%Y%m%d"
现在,如果未定义QUERYDATE_CONVERT
,则在变量替换后,上述变为:
date -d +"%Y%m%d"
因此,字符串+"%Y%m%d"
现在是-d
选项的参数。由于不存在此类日期,date
将显示错误消息:
date: invalid date `+%Y%m%d'
因为shell对其变量使用大写名称,所以最好使用shell变量的混合或小写名称。这可以确保您不会意外覆盖重要的内容。
由于这里使用的替换很简单,因此可以用shell扩展替换对sed
的调用,如sputnick所示。
这可能不适用于您的最终应用,但在如图所示的脚本中,行:
echo $(date -d $QUERYDATE_CONVERT +"%Y%m%d")
可以替换为:
date -d $QUERYDATE_CONVERT +"%Y%m%d"
MarkReed指出,在bash
下,管道可以替换为here-string:
QUERYDATE_CONVERT=$(sed 's/"\|T.*//g' <<<"$QUERYDATE")
here-string消除了一个过程,因此应该更有效率。由于此问题已标记为bash
,因此这是一个很好的解决方案。
但是,这里的字符串不是POSIX。例如,它们不会在dash
下工作,这是类似debian的系统上的默认/bin/sh
。如果使用here-document,仍然可以在保持POSIX兼容性的同时消除额外的进程:
QUERYDATE_CONVERT=$(sed 's/"\|T.*//g' <<EOF
$QUERYDATE
EOF
)
答案 1 :(得分:0)
使用bash&#39; parameter expansion:
#!/bin/bash
while read querydate; do
querydate="${querydate%T*}"
echo "$(date -d "${querydate//\"/}" +"%Y%m%d")"
done < test.txt
答案 2 :(得分:0)
#!/bin/bash
while read QUERYDATE
do
echo $QUERYDATE | sed 's/"\|T.*//g'
echo $(date -d $QUERYDATE_CONVERT +"%Y%m%d")
done < test.txt
这段代码正在影响您的脚本
echo $QUERYDATE | sed 's/"\|T.*//g'
这只是打印从字符串中取出的日期(sed输出)但不存储它。因此变量$QUERYDATE
保持不变
"2014-09-08T01:49:31Z"
"2014-01-30T03:41:41Z"
"2012-05-23T16:08:45Z"
"2012-05-04T10:16:04Z"
"2012-04-05T15:27:40Z"
要解决此问题,您可以尝试更换:
echo $QUERYDATE | sed 's/"\|T.*//g'
使用:
QUERYDATE=`echo $QUERYDATE | sed 's/"\|T.*//g'`
现在您将获得所需的输出,因为修改了非格式化日期并将其重新分配给变量QUERYDATE。
输出
20140908
20140130
20120523
20120504
20120405