単一の変数ではパターン置換が機能しないのはなぜですか?

単一の変数ではパターン置換が機能しないのはなぜですか?

以下のセッションの記録をご覧ください。

$ mkdir temp
$ cd temp/
$ touch file{1..5}
$ ls
file1  file2  file3  file4  file5
$ SRC=file; TGT=ram
$ for f in file* ; do mv $f ${f/$SRC/$TGT} ; done
$ ls
ram1  ram2  ram3  ram4  ram5
$ PAT=ram/file
$ for f in ram* ; do mv $f ${f/$PAT} ; done
mv: 'ram1' and 'ram1' are the same file
mv: 'ram2' and 'ram2' are the same file
mv: 'ram3' and 'ram3' are the same file
mv: 'ram4' and 'ram4' are the same file
mv: 'ram5' and 'ram5' are the same file

SRCと をTGT別々の変数として指定した場合はパターン置換が機能するのに、 を単一の変数として指定した場合は機能しないのはなぜですかPAT?

私の理解では、置換は内側から外側に処理されるため、外側の中括弧内の文字列、つまり またはf/$SRC/$TGTはまたはf/$PATに同様に処理され、その後、実際の新しいファイル名を与えるために再度処理されるはずです。しかし、どうやらそうは行われていないようです…f/file/ramf/ram/file

私は最新のアップデートを適用した Kubuntu Bionic LTS で Bash 4.4.18 を使用しています。

答え1

からBashマニュアル:

${parameter/pattern/string}
pattern、ファイル名の展開と同様に、パターンを生成するために展開されます。[...] がstringnull の場合、 の一致patternは削除され、/次のパターンは省略される場合があります。

つまり、パターンと置換は展開後に決定されるのではなく、まずパターンと置換コンポーネントが特定され、それから展開されます。 では${f/$PAT}、 の全体が$PATパターンになり、置換は空になります。

関連情報