在 Linux 和 Solaris 上格式化字符串

Format string on Linux and Solaris

我有一个 Korn Shell 脚本,其中一部分是它采用 YYYYMMDD 格式的给定日期并以 YYYY/MM/DD 格式输出。一开始我试过

typeset displaystart=`date --date="${gbegdate}" '+%Y/%m/%d'`

在 Linux 上运行良好,但 Solaris 的 date 没有 --date 选项。然后我尝试了

typeset displaystart=`echo ${gbegdate:0:4}`/`echo ${gbegdate:4:2}`/`echo ${gbegdate:6:2}`

也适用于 Linux,但在 Solaris 上它只输出 //

如何以适用于 Linux 和 Solaris 的方式格式化此日期字符串?

Korn shell 没有 ${variable:start:length} 语法;这是 POSIX shell 语法的 bash 扩展。

您可以改用 echo "$variable" | cut -cstart-end

typeset displaystart=`echo $gbegdate | cut -c1-4`/`echo $gbegdate | cut -c5-6`/`echo $gbegdate | cut -c7-8`

或者您可以更改脚本以使用 bash 而不是 ksh

${variable:start:length} 对 POSIX shell 语法的扩展是在 1993 年发布的 ksh 版本中引入的,准确命名为 ksh93,并且bash 1.13 同年推出。

Advanced bash scripting guide from the Linux Documentation Project 状态:

Variable expansion / Substring replacement

These constructs have been adopted from ksh.

${var:pos}

Variable var expanded, starting from offset pos.

${var:pos:len}

Expansion to a max of len characters of variable var, from offset pos. See Example A-13 for an example of the creative use of this operator.

问题是在 Solaris 10 及更早版本上,/bin/ksh 提供了以前的 ksh 标准,ksh88,它没有实现此功能。

另一方面,在Linux上,ksh通常是ksh93,支持子串提取。这就解释了为什么你的脚本在 Linux ksh 下工作(如果你真的在 ksh 上测试过它)

ksh93 的旧派生版本可在 Solaris 10 上使用。它被命名为 dtksh ans 位于 /usr/dt/bin/dtksh。您的命令应该可以正常工作,但是我不建议完全切换到 dtksh,这个 shell 正在从 Solaris 中逐步淘汰,但您仍然可以从常规 ksh 脚本中使用它来解决您的问题:

typeset displaystart=$(/usr/dt/bin/dtksh -c "gbedate=$gbedate; echo ${gbegdate:0:4}/${gbegdate:4:2}/${gbegdate:6:2}")

请注意,Solaris 11 和更新版本同时提供 GNU dateksh93,因此您一开始就不会遇到这个问题。