Как привыкнуть к работе по параметрическим расширениям?

Текущий сценарий -

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}.

Есть ли в этом фрагменте явные ошибки?

0
задан 4 July 2018 в 01:03

1 ответ

Основная проблема заключается в том, что $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
0
ответ дан 4 July 2018 в 01:03

Другие вопросы по тегам:

Похожие вопросы: