请参阅以下会议记录:
$ 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
?
我的理解是,替换是从里到外处理的,因此外部大括号内的字符串 ie f/$SRC/$TGT
orf/$PAT
应该同等地处理为f/file/ram
or f/ram/file
,然后再次处理以给出实际的新文件名。但显然这并没有这样做……
我在 Kubuntu Bionic LTS 上使用 Bash 4.4.18 并进行了最新更新。
答案1
从Bash 手册:
${parameter/pattern/string}
被pattern
扩展以产生一个模式,就像文件名扩展一样。 [...] 如果string
为 null,则pattern
删除 的匹配项,并且/
可以省略以下模式。
所以,这个过程并不是在扩展之后确定模式和替换。相反,首先识别模式和替换组件,然后然后它们被扩展了。在 中${f/$PAT}
, 的整体$PAT
成为模式,并且替换为空。