Se você não insistir em usar sed , considere usar dirname :
S="dir/subdir/othersubdir/file.txt"
P=$(dirname $S)
echo $P
dir/subdir/othersubdir
S="dir/file.txt"
P=$(dirname $S)
echo $P
dir
Eu tenho uma string parecida com essa
dir/subdir/othersubdir/file.txt
Mas também pode parecer
dir/file.txt
ou
dir/subdir/file.txt
Agora, estou criando um script em que $P é o caminho completo para o diretório file.txt is.
Agora eu uso isso
sed 's/\/.*txt//g'
Para substituir qualquer coisa que termine com txt e venha depois de um / . Isso funciona bem quando há algo como dir/file.txt , mas nenhum dos meus outros exemplos. Como posso corrigir para que corresponda ao que eu quero?
Não quero corresponder nenhum subdiretório antes de .*txt . Desejo remover apenas o nome base do arquivo.
Aqui está o comando sed :
$ P="dir/subdir/othersubdir/file.txt"
$ sed -r 's/^(.*)\/.*\.txt$//' <<< $P
dir/subdir/othersubdir
No comando sed acima, capturamos qualquer coisa .* do início ^ da variável P que termina $ com /*.txt , que é conhecido como um grupo capturado com como seu beck- referência porque usou um par de parênteses em torno dele (.*) , em seguida, na parte de substituição do comando sed, nós imprime apenas grupo capturado usando sua referência de volta.
Se você está usando zsh life é muito mais simples, use apenas o modificador :h :
$ var='dir/subdir/othersubdir/file.txt'
$ echo "$var:h"
dir/subdir/othersubdir