
Bitte sehen Sie sich das Sitzungsprotokoll unten an:
$ 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
Warum funktioniert die Musterersetzung, wenn ich SRC
und TGT
als getrennte Variablen angebe, aber nicht, wenn ich sie als einzelne Variable angebe PAT
?
Nach meinem Verständnis werden Ersetzungen von innen nach außen verarbeitet, sodass die Zeichenfolge innerhalb der äußeren Klammern, also f/$SRC/$TGT
oder , genauso wie oder f/$PAT
verarbeitet werden sollte , was dann wiederum verarbeitet wird, um den tatsächlichen neuen Dateinamen zu ergeben. Aber anscheinend wird das nicht so gemacht …f/file/ram
f/ram/file
Ich verwende Bash 4.4.18 auf Kubuntu Bionic LTS mit den neuesten Updates.
Antwort1
${parameter/pattern/string}
Diespattern
wird erweitert, um genau wie bei der Dateinamenerweiterung ein Muster zu erzeugen. [...] Wennstring
null ist,pattern
werden Übereinstimmungen von gelöscht und das/
folgende Muster kann weggelassen werden.
Der Prozess ist also nicht so, dass das Muster und der Ersatz nach der Erweiterung bestimmt werden. Stattdessen werden zuerst die Muster- und Ersatzkomponenten identifiziert undDannsie werden erweitert. In wird ${f/$PAT}
das gesamte Muster $PAT
zum Muster und der Ersatz ist leer.