bash 从旧版 BSD-`ls` 的输出生成 iso-time 的脚本

bash script to generate iso-time from output of older BSD-`ls`

我想生成 iso 样式的时间信息 (YYYY-MM-DDTmm:hh:ss) 带有较旧 ls 命令的 bsd-ish 系统(man 表示它是 BSD-ls) 并且没有 --time-style 选项。我得到的最好的是

$ ls -lT log.out
-rw-r--r--  1 admin4  staff  49152 Jul 17 09:38:38 2018 log.out

有没有一种简单的方法可以在 bash-将脚本转换为 iso 样式?

$ timestamp="$(ls -lT log.out | iso-timestamp-gen)"

非常感谢您的帮助

首先,cut 过期部分:

DATE=`echo - | cut -f9-12 -d' '`;

然后使用 date:

将其转换为时间戳
echo `date --date="$DATE" +"%s"`;

iso-timestamp-gen 文件:

#!/bin/bash
DATE=`echo - | cut -f9-12 -d' '`;
echo `date --date="$DATE" +"%s"`;

解决我们的问题

timestamp="$(ls -lT log.out | iso-timestamp-gen)"

@Hamidreza 向我们指出了 date 命令的方向:一个 我们的工程师想出了这个细长的内联解决方案:

timestamp=$(date -j -f '%b %e %T %Y' \
    "$(ls -lT $f | awk '{ print , , ,  }')" \
    +'%F_%T')

其中变量 f 包含要考虑的文件的名称。 在第 2 行中,awkls -lT.

的输出中提取日期部分(字段 6 到 9)

与此 "DateToConvert" date 一起提供匹配 输入格式 "%b %e %T %Y" 以及请求的输出格式 "%F_%T"。 我们在中查找了转换规范 strftime(3).

到目前为止,我们都不知道您不仅可以使用 date 读取和设置系统时钟,也用于转换日期 一种格式到另一种格式:

date -j -f "${InputFormat}" "${DateToConvert}" +"${OutputFormat}"

我们有些尴尬地向对方坦白了这一点,然后 决定好好利用新的洞察力。 几个小时后,我们将以下新助手添加到我们的工具箱中。 它从 ls -lT 的输出中提取日期并将其转换为 其他格式。到目前为止,我们只包含了 iso 格式和一种格式 这在使用 touch(1) 命令时很方便。此列表将来可能会扩展。

#!/bin/bash
#
# conv-date-of-llT.sh
#   convert date output of ls -lT ($OSTYPE == darwin14)
#       - to iso-format YYYY-MM-DD_hh:mm:ss or
#       - to "touch" format: [[CC]YY]MMDDhhmm[.SS]
#
# hppo, 2018-07-20

# strip [=13=] of path and ext
Arg0="${0##*/}"     # peel off path
Arg0="${Arg0%%.*}"  # peel off ext

USAGE="${Arg0} [ -iso | -touch ]"

# select output format
case "fmt" in
    fmt|fmt-iso|fmtiso)     # YYYY-MM-DD_hh:mm:ss
        OutputFormat="%F_%T" ;;
    fmt-touch|fmttouch)     # YYYYMMDDhhmm
        OutputFormat="%Y%m%d%H%M" ;;
    *)
        1>&2 echo -e "${Arg0}: no such output format ''\nUsage: ${USAGE}"; exit 1 ;;
esac

# input: output of "ls -lT file" on darwin-14
#       -rwxr-xr-x  1 admin4  staff  387 Jul 17 01:38:24 2018 file
#       1       2 3   4  5   6   7  8        9    10
#
# Field 6 - 9: month(%b) day(%e) time(%T) year(%Y), cf strftime(3)
InputFormat="%b %e %T %Y"

# assume stdin is fed by output of ls -lT
DateToConvert="$(awk '{ print , , ,  }')"

date -j -f "${InputFormat}" "${DateToConvert}" +"${OutputFormat}"