Shell 参数扩展在 AIX 中不起作用

Shell 参数扩展在 AIX 中不起作用

我正在尝试替换在 AIX 中不起作用的特定字符串,但当我在 RHEL 上运行它时,我能够获得预期的输出。

这是命令:

filename=25_032021_abcdefghijklmn.txt; mv /u/foo/test/25_032021_test_${filename:10:14}.txt /u/foo/test/25_032021_test_${filename:10:14}.txt.tmpExtension

这是我在 AIX 上运行此命令时遇到的错误

ksh: /u/foo/test/25_032021_test_${filename:10:14}.txt: 0403-011 The specified substitution is not valid for this command.

知道我可能做错了什么吗?

答案1

${param:offset:length}是由 ¹ 引入的ksh93,它在 中不可用ksh88。因此,您需要确保该脚本由 ksh93 解释,而不是 ksh88。

还要记住,在大多数类似 Bourne 的 shell 中,至少在列表上下文中,参数扩展必须被引用。

您可以在启用行编辑器的交互中键入Esc, Ctrl+ (在或 或后面)来检查其版本。Vkshset -o emacsvigmacs

在这里,${filename:10:14}您可以使用

filename=25_032021_abcdefghijklmn.txt
id="${filename%.*}" # remove extension from the end
id="${id#*_*_}"     # remove up to second _ from the start
mv "/u/foo/test/25_032021_test_$id.txt" \
   "/u/foo/test/25_032021_test_$id.txt.tmpExtension"

要从开头删除 10 个字符而不是*_*_,请使用${param#??????????}。因此,假设id=${filename:10:14}至少filename有 24 个字符,则相当于:

id=${filename#??????????}       # remove 10 characters from the start
id=${id%"${id#??????????????}"} # remove from the end: $id stripped of
                                # its first 14 characters

这些${param#pattern}${param%pattern}是在 的早期版本中引入的ksh(已经在 ksh85 中),甚至由 POSIX for 指定,因此您应该在任何时候或现在sh都能找到它们。shksh

或者,您也可以走前克什时代的古老道路,诉诸expr²。

id=`expr "x$filename" : 'x.\{10\}\(.\{14\}\)'`

或者:

id=`expr "x$filename" : 'x.\{10\}\(.\{0,14\}\)'`

${filename:10:14}(当$filename字符数少于 24 个时,与 ksh93 的更严格等效)。

请注意,expr如果它输出的是数字 0 或空字符串的表示或正则表达式不匹配,则会返回失败退出状态,因此|| true如果启用了该errexit选项,则可能需要附加 a ,因此它不会123456789_00000000000000.txt例如,导致 shell 在调用的文件上退出。

如果exprID以换行符结尾(该换行符将被命令替换删除)。


1bash自 2.0(1996 年底)、mksh自 R30(2007)和zsh自 4.3.11(2010 年底)以来也可用,但自 1991 年的 2.0 起zsh就有$param[first,last]

² 虽然\{n,m\}regexp 运算符如今已成为标准操作符,但在 ksh 出现之前的那些日子里,它是不可用的,并且您必须使用例如.\{10\}替换。..........

相关内容