Bash 将多个纪元值转换为日期时间
Bash convert a number of epoch values to datetime
我有许多格式为 foo_[SECONDS.MILLISECONDS]_bar.tar.gz
的文件,对于每个文件,我想为每个文件获取一个日期时间值 (YYYYMMDDHHMMSS)。
到目前为止我有
ls -1 /filestore/*.tar.gz | cut -d _ -f 2 | date -f -
但是这个错误与
date: invalid date '1467535262.712041352'
如何将纪元值的 bash 管道转换为日期时间字符串?
MWE
mkdir tmpBLAH
touch tmpBLAH/foo_1467483118.640314986_bar.tar.gz
touch tmpBLAH/foo_1467535262.712041352_bar.tar.gz
ls -1 tmpBLAH/*.tar.gz | cut -d _ -f 2 | date -f -
要将纪元时间转换为 datetimem,请尝试以下命令:
date -d @1346338800 +'%Y%m%d%H%M%S'
1346338800是一个纪元时间
关于你的情况,命令行如下:
echo 1467535262.712041352 | cut -d '.' -f 1 | xargs -I{} date -d @{} +'%Y%m%d%H%M%S'
您将获得:
20160703174102
是这样的吗?
for f in /filestore/*.tar.gz; do
epoch=${f#*_}
date -d @${epoch%%.*} +%Y%m%d%H%M%S
done
date
命令的语法因平台而异;我假定 GNU date
,正如 Linux 上常见的那样。 (如果你在每个时间戳之前添加 @
,你可能会使用 date -f
,但我现在不在可以测试它的地方。)运行 循环使一些事情变得更容易,例如打印输入文件名和转换日期,否则管道将是最有效和惯用的解决方案。
你可以这样做:
for i in foo_*_bar.tar.gz; do date -d "@$(cut -d_ -f2 <<<"$i")" '+%Y%m%d%H%M%S'; done
纪元时间由 -d @<time>
提供,所需格式为 '+%Y%m%d%H%M%S'
。
示例:
% for i in foo_*_bar.tar.gz; do date -d "@$(cut -d_ -f2 <<<"$i")" '+%Y%m%d%H%M%S'; done
20160703001158
20160703144102
首先,ls
的-1
选项没有用,因为ls默认每行输出一个文件,只是当输出是终端(不是管道)时,它漂亮地打印在列中。您可以通过 运行 ls | cat
.
来检查该事实
然后,date 仅在前缀为 @
时才安全地转换纪元时间戳。
% date -d 0
Sun Jul 3 00:00:00 CEST 2016
% LANG=C date -d @0
Thu Jan 1 01:00:00 CET 1970
% date -d 12345
date: invalid date '12345'
% date -d @12345
Thu Jan 1 04:25:45 CET 1970
给出:
printf "%s\n" tmpBLAH/foo_*_bar.tar.gz | sed 's/.*foo_/@/; s/_bar.*//' | date -f -
我有许多格式为 foo_[SECONDS.MILLISECONDS]_bar.tar.gz
的文件,对于每个文件,我想为每个文件获取一个日期时间值 (YYYYMMDDHHMMSS)。
到目前为止我有
ls -1 /filestore/*.tar.gz | cut -d _ -f 2 | date -f -
但是这个错误与
date: invalid date '1467535262.712041352'
如何将纪元值的 bash 管道转换为日期时间字符串?
MWE
mkdir tmpBLAH
touch tmpBLAH/foo_1467483118.640314986_bar.tar.gz
touch tmpBLAH/foo_1467535262.712041352_bar.tar.gz
ls -1 tmpBLAH/*.tar.gz | cut -d _ -f 2 | date -f -
要将纪元时间转换为 datetimem,请尝试以下命令:
date -d @1346338800 +'%Y%m%d%H%M%S'
1346338800是一个纪元时间
关于你的情况,命令行如下:
echo 1467535262.712041352 | cut -d '.' -f 1 | xargs -I{} date -d @{} +'%Y%m%d%H%M%S'
您将获得:
20160703174102
是这样的吗?
for f in /filestore/*.tar.gz; do
epoch=${f#*_}
date -d @${epoch%%.*} +%Y%m%d%H%M%S
done
date
命令的语法因平台而异;我假定 GNU date
,正如 Linux 上常见的那样。 (如果你在每个时间戳之前添加 @
,你可能会使用 date -f
,但我现在不在可以测试它的地方。)运行 循环使一些事情变得更容易,例如打印输入文件名和转换日期,否则管道将是最有效和惯用的解决方案。
你可以这样做:
for i in foo_*_bar.tar.gz; do date -d "@$(cut -d_ -f2 <<<"$i")" '+%Y%m%d%H%M%S'; done
纪元时间由 -d @<time>
提供,所需格式为 '+%Y%m%d%H%M%S'
。
示例:
% for i in foo_*_bar.tar.gz; do date -d "@$(cut -d_ -f2 <<<"$i")" '+%Y%m%d%H%M%S'; done
20160703001158
20160703144102
首先,ls
的-1
选项没有用,因为ls默认每行输出一个文件,只是当输出是终端(不是管道)时,它漂亮地打印在列中。您可以通过 运行 ls | cat
.
然后,date 仅在前缀为 @
时才安全地转换纪元时间戳。
% date -d 0
Sun Jul 3 00:00:00 CEST 2016
% LANG=C date -d @0
Thu Jan 1 01:00:00 CET 1970
% date -d 12345
date: invalid date '12345'
% date -d @12345
Thu Jan 1 04:25:45 CET 1970
给出:
printf "%s\n" tmpBLAH/foo_*_bar.tar.gz | sed 's/.*foo_/@/; s/_bar.*//' | date -f -