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
。したがって、スクリプトがksh88ではなくksh93によって解釈されていることを確認する必要があります。
また、ほとんどのBourne様シェルでは、少なくともリストコンテキストでパラメータ拡張を引用する必要があることに注意してください。
対話型行エディタでEsc、Ctrl+(または後ろ)を入力してバージョンを確認できます。Vksh
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}
24filename
文字を仮定すると、次のようになります。
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}
バージョンのksh85(すでにksh85にあります)に導入され、ksh
POSIXでも指定されているので、sh
いつでも見つけることができます。sh
ksh
あるいは、カシガル以前の時代の古代の道をたどるか、²に頼ることもできますexpr
。
id=`expr "x$filename" : 'x.\{10\}\(.\{14\}\)'`
または:
id=`expr "x$filename" : 'x.\{10\}\(.\{0,14\}\)'`
${filename:10:14}
($filename
文字数が24個未満の場合、ksh93とより厳密に同じです。)
expr
数値ゼロまたは空の文字列表現を出力するか、正規表現が一致しない場合は失敗した終了ステータスを返すため、オプションが|| true
有効になっている場合はerrexit
そうでないようにaを追加する必要があります。123456789_00000000000000.txt
たとえば、次のようになります。原因 シェルは呼び出しファイルで終了します。
expr
もしID改行文字で終わります(コマンド置換によって削除されます)。
1 bash
2.0(1996年末)、mksh
R30(2007)および4.3.11(2010年末)から利用可能ですが、zsh
1991年2.0からzsh
利用可能でした$param[first,last]
。
²\{n,m\}
正規表現演算子は今日標準演算子ですが、ksh以前には使用できず、置換などを使用する必要がありました.\{10\}
。..........