Se a sua variável contiver apenas um dígito, o que você fez está correto:
sed "$lnum!d" cloud.cpp
Para passar a variável shell para sed em geral, leia esta resposta .
Agora, você fez isso corretamente neste caso, mas ainda não funciona. Isso é devido ao seu shell, que provavelmente bash , zsh ou csh . Esses shells suportam a expansão do histórico, que é denotada por ! (esse recurso é original de csh e copiado posteriormente por bash e zsh ).
Em bash , zsh , a expansão de histórico é ativada por padrão na sessão interativa e será executada entre aspas duplas.
Em zsh :
$ seq 10 | sed "10!d" # <-- press enter
$ seq 10 | sed "10dash"
como dash é meu último comando no histórico, comece com d .
Em bash :
$ seq 10 | sed "10!d"
bash: !d": event not found
como eu não tenho nenhum comando no bash history comece com d .
Você pode desativar a expansão do histórico:
set +H
ou:
set +o histexpand
em bash e:
set -K
ou:
setopt nohistexpand
em zsh .
Para uma forma mais portátil, sem confiar nas suas opções de shell, você sempre pode fazer:
sed "$lnum"\!d cloud.cpp
que faz com que seu shell trate ! literalmente.