замена внутри файла
Я использую для этого такую конструкцию:
#! /bin/bash
subst()
{
	eval "cat <<EOF
`cat \"$1\"`
EOF"
}
. ./config
subst ./dhcpd.conf.in > ./dhcpd.conf
При этом dhcpd.conf.in выглядит так:
ddns-update-style interim;
ignore client-updates;
subnet ${NET}.0 netmask 255.255.255.0 {
        option routers                  ${NET}.1;
        option subnet-mask              255.255.255.0;
        option domain-name-servers      192.168.248.21;
        option root-path                "${NET}.1:/tftpboot/tensilica/rootfs/${ROOTFS}${NFS_MOUNT_OPTIONS}";
        range dynamic-bootp ${NET}.128 ${NET}.128;
        default-lease-time 21600;
        max-lease-time 43200;
}
а config -- так:
NET=192.168.135
ROOTFS=cp0_latest
NFS_MOUNT_OPTIONS=${NFS_MOUNT_OPTIONS},noac
IF_CONFIG="$NET.1 up"
CONFIG=debug-kc705-cp0_latest
KERNEL_IMAGE=uImage
Т.е. в функции subst внутренний cat подставляет тело файла-шиблона, а eval выполняет внешний cat с подстановкой shell-переменных, зачитанных из config. Нужно понимать, что и шаблон и конфиг в этом скрипте могут выполнять произвольные команды, т.е. нельзя их брать у недоверенного пользователя.