Текущий сценарий -
for r in $path/[0-9]*.tst; do
sed -i s/val1/${r%.tst}/ $path/foo.bar
sed -i s/val2/${var2}/ $path/foo.bar
sed -i s/val3/${var3}/ $path/foo.bar
sed -i s/val4/${var4}/ $path/foo.bar
cat $path/foo.bar
done
Значения 2-4 работают нормально; однако val1 остается неизменным. Это верно, даже когда я использую $ {r} вместо $ {r% .tst}.
Есть ли в этом фрагменте явные ошибки?
Основная проблема заключается в том, что $r
будет выглядеть как path/file.tst
, поэтому при расширении (с расширением точки или без него) sed
увидит что-то вроде
sed s/val1/path/file/
, что приведет к ошибка, потому что /
в строке замены интерпретируется как завершающий /
из sed s/pattern/replacement/
. Вы можете преодолеть это, выбрав любой другой символ в качестве разделителя шаблонов sed - выберите то, что не будет быть в вашем имени файла или пути, например @
(хотя, конечно, является допустимым символом имени файла). Итак,
"s@val1@${r%.tst}@"
(я использовал здесь двойные кавычки: они позволят расширение переменных, предотвращая другие потенциальные ошибки, такие как расширение глобуса).
Из соображений стиля (и эффективности) я бы предложил не делать несколько вызовов sed
для редактирования одного и того же файла - вы можете связать несколько выражений замены в GNU sed с помощью -e
] например,
sed -i -e "s@val1@${r%.tst}@" -e "s@val2@${var2}@" -e ...
или воспользуйтесь опцией -f scriptfile
и используйте следующий документ:
for r in "$path"/[0-9]*.tst; do
sed -i -f- "$path/foo.bar" << EOF
s@val1@${r%.tst}@
s@val2@${var2}@
s@val3@${var3}@
s@val4@${var4}@
EOF
cat "$path/foo.bar"
done