Um dos fundamentos do uso do regex é que os padrões são gananciosos por natureza ao especificar o curinga. Embora a resposta proposta por @uloBasEI seja certamente uma resposta funcional, também requer o uso do comando basename. A pergunta original do @Shixons solicita uma solução usando apenas sed.
Antes de continuar, é sempre útil saber qual versão do sed é o alvo. Estou assumindo o BSD (como fornecido com o OSX).
Em primeiro lugar, o padrão proposto na pergunta original não funciona porque ele captura tudo, desde o início da string de entrada até o último ponto. Sem âncoras, esta pesquisa irá engolir tudo da esquerda para a direita. O padrão de correspondência "/ 1", portanto, é tudo até e incluindo o último ponto. Até mesmo um nome de arquivo com vários pontos será engolido inteiro. Não é o resultado desejado.
O primeiro passo é estabelecer uma estratégia para identificar padrões. Aqui, você gostaria de se livrar de tudo à esquerda do nome do arquivo (lidaremos com a extensão mais tarde):
out_file="$(echo $in_file | sed 's/^\(\/.*\/\)*.*//')"
A pesquisa corresponde ao início da string. Ele corresponde a um padrão de "/.*" zero ou mais vezes e exclui tudo depois. Nós imprimimos os padrões combinados com "\ 1". Nós não estamos buscando globalmente; estamos pesquisando desde o começo da string, especificando a âncora.
Temos mais clareza ativando a opção "-E", para que não seja necessário escapar dos parênteses:
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*.*//')"
Então agora temos a parte à esquerda. Vamos adicionar a parte à direita. Note que precisamos manter a parte esquerda como um padrão, porque é assim que podemos especificar que ela aparece zero ou mais vezes. Tudo o que fazemos agora é adicionar um padrão para a parte à direita:
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)//')"
Apenas imprimimos a segunda correspondência, descartando tudo, menos o nome do arquivo. Mas ainda precisamos remover a extensão do nome do arquivo.
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)\..*$//')"
O "$" no final é opcional.
Por fim, para adicionar a nova extensão que você acabou de revisar da seguinte forma:
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)\..*$/.mp4/')"
Uma otimização adicional é tornar a primeira barra opcional opcional para lidar com caminhos relativos:
out_file="$(echo $in_file | sed -E 's/^([\/]?.*\/)*(.*)\..*$/.mp4/')"
Eu me deparei com essa pergunta sendo preguiçoso enquanto procurava por um padrão sed para substituir basename . Estou trabalhando em um sistema separado que não tem esse comando instalado.