私たちがコメントで行ったすべての面白い議論 (それは本当に面白いスレッドでした) から、私は多かれ少なかれ (おそらくより少ない) あなたが何を望んでいるのかを理解しました. 私が理解したことを言い換えさせてください (これがあなたが正確に要求したものでない場合は、ご容赦ください)。
負でない 3 つの数値引数X
、Y
およびZ
(先頭に0
's がある可能性があります) を使用するスクリプトが必要であり、次の場所X<Y
に出力します。test-M => test-N
M
X
からまでの範囲で、 の文字数がおよびの最大文字数になるように、左側に 's がY
埋め込まれます0
M
X
Y
N=M+Z
の文字数が、、およびの最大文字数に0
なるように、左に 's が埋め込まれます。例えば、N
X
Y
Z
Y+Z
$ ./script 01 04 00220
test-01 => test-00221
test-02 => test-00222
test-03 => test-00223
test-04 => test-00224
$ ./script 99 101 0
test-099 => test-099
test-100 => test-100
test-101 => test-101
$ ./script 99 101 00000
test-099 => test-00099
test-100 => test-00100
test-101 => test-00101
$ ./script 00 02 99
test-00 => test-099
test-01 => test-100
test-02 => test-101
mv
また、別のコマンドの出力を解析しなくても対応するファイルを取得できるように、bash ソリューションが必要です。
では、掘り下げて興味深いものを見つけていただければ幸いです (注意してください。出力はmv -nv xxx yyy
ではなくの形式です。これに満足したらtest-x => test-y
、 を削除してください)。echo
#!/bin/bash
prepend_source=test-
prepend_target=test-
append_source=
append_target=
shopt -s extglob
die() { printf >&2 "%s\n" "$@"; exit 1; }
is_number() { [[ $1 = +([[:digit:]]) ]]; }
is_in_range() { [[ -z ${1//0/} ]] || [[ ${1/#+(0)} = $((10#$1)) ]]; }
maxlength() {
local u l=0 retvar=$1
shift
for i in "$@"; do
u=${#i}
((u>l)) && ((l=u))
done
printf -v "$retvar" "%d" "$l"
}
X=$1
Y=$2
Z=$3
is_number "$X" || die "First argument is not a valid number"
is_number "$Y" || die "Second argument is not a valid number"
is_number "$Z" || die "Third argument is not a valid number"
(( 10#$X <= 10#$Y )) || die "Error: first argument is greater than second"
is_in_range "$X" || die "First argument out of range"
is_in_range "$Y" || die "Second argument out of range"
is_in_range "$Z" || die "Third argument out of range"
(( 10#$Y + 10#$Z >= 0 )) || die "Sum of second and last arguments is out of range"
maxlength "length_s" "$X" "$Y"
maxlength "length_t" "$X" "$Y" "$Z" "$((10#$Y+10#$Z))"
for ((i=10#$X;i<=10#$Y;++i)); do
printf -v source "%s%.${length_s}d%s" "$prepend_source" "$i" "$append_source"
printf -v target "%s%.${length_t}d%s" "$prepend_target" "$((10#$Z+$i))" "$append_target"
# Here we're all done!
echo mv -nv -- "$source" "$target" || die "Problem in mv" # or another error handle
done
変数prepend_source
、append_source
、prepend_target
をappend_target
スクリプトの先頭に追加したので、必要なものに簡単に置き換えることができます。オプションの解析を追加して、コマンド ラインから設定できるようにすることもできます (私がやると主張しない限り、演習として残しておいてください)。
警告。数値は bash によって直接処理されるため、bash の算術範囲内からそれらを使用する必要があります。これは、64 ビット マシンでは (非常に可能性が高い) [-9223372036854775808,9223372036854775807] です。そのため、その前にできることはたくさんあります。明示的なチェックを追加したので、何かがこの範囲外に出てもスクリプトが壊れることはありません。これが本当に制限である場合は、いつでも代わりにbc
orを使用できdc
ます。bc
orのdc
実装は、演習として読者に任せます。ちなみに、これは非負の整数でのみ機能します。
あなたのソリューションは、これと同じくらい堅牢で一般的ですか?