Por que a substituição de padrões não funciona a partir de uma única variável?

Por que a substituição de padrões não funciona a partir de uma única variável?

Por favor, veja a transcrição da sessão abaixo:

$ 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

Por que a substituição de padrão funciona se eu fornecer SRCand TGTcomo variáveis ​​separadas e não se eu fornecê-las como uma única variável PAT?

Meu entendimento é que as substituições são processadas de dentro para fora e, portanto, a string dentro do conjunto externo de colchetes, ou seja, f/$SRC/$TGTor f/$PATdeve ser igualmente processada para f/file/ramor f/ram/file, que é processada novamente para fornecer o novo nome real do arquivo. Mas aparentemente isso não é feito assim…

Estou usando o Bash 4.4.18 no Kubuntu Bionic LTS com as atualizações mais recentes.

Responder1

Deo manual do Bash:

${parameter/pattern/string}
O patterné expandido para produzir um padrão exatamente como na expansão do nome do arquivo. [...] Se stringfor nulo, as correspondências de patternsão excluídas e o /padrão a seguir pode ser omitido.

Portanto, o processo não é tal que o padrão e a substituição sejam determinados após a expansão. Em vez disso, primeiro o padrão e os componentes de substituição são identificados eentãoeles são expandidos. Em ${f/$PAT}, a totalidade $PATse torna o padrão e a substituição fica vazia.

informação relacionada