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.
知道我可能做錯了什麼嗎?
${param:offset:length}
由ksh93
¹ 介紹,它在ksh88
. 所以你需要確保腳本是由 ksh93 而不是 ksh88 解釋的。還要記住,至少在列表上下文中,必須在大多數類似 Bourne 的 shell 中引用參數擴展。
您可以在啟用了行編輯器的互動中鍵入
Esc
,Ctrl
+ (在或之後)以檢查其版本。V``ksh``set -o emacs``vi``gmacs
在這裡,
${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 指定用於sh
,因此您應該在任何時候sh
或ksh
這些日子裡找到它們。或者您可以從前 ksh 時代走古老的道路並訴諸
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,所以它不會導致 shell 退出123456789_00000000000000.txt
例如呼叫的文件。如果id以換行符結尾(這將被命令替換剝離),該
expr
方法也將無法正常工作。¹
bash
自 2.0(1996 年末)、mksh
R30(2007 年)和zsh
4.3.11(2010 年末)起也可使用,但自 1991 年的 2.0 起zsh
就有。$param[first,last]
² 雖然
\{n,m\}
regexp 運算符在今天是標準的,但在 ksh 之前的那些日子裡它是不可用的,你不得不.\{10\}
用..........
例如替換。