Разделите базовое имя файла, сохраните часть каталога

У меня есть строка, которая выглядит примерно так:

dir/subdir/othersubdir/file.txt 

Но это также может выглядеть

 dir/file.txt 

или

 dir/subdir/file.txt 

Теперь, я делаю скрипт, где $P полный путь к каталогу были file.txt .

Теперь я использую это

 sed 's/\/.*txt//g' 

Чтобы заменить все, что заканчивается на txt, и появляется после / . Это отлично работает, когда есть что-то вроде dir/file.txt , но не какие-либо другие мои примеры. Как я могу исправить, чтобы он соответствовал тому, что я хочу?

Я не хочу сопоставлять какие-либо подкаталоги раньше .*txt . Я хочу удалить только имя базы данных.

Если вы не настаиваете на использовании sed вы можете использовать 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 

Вот команда sed :

 $ P="dir/subdir/othersubdir/file.txt" $ sed -r 's/^(.*)\/.*\.txt$/\1/' <<< $P dir/subdir/othersubdir 

В приведенной выше команде sed мы /*.txt что угодно .* /*.txt с начала переменной переменной P которая заканчивается $ с /*.txt , которую она называется захваченной группой с \1 качестве ссылки beck-ссылки, потому что она использует пару круглых скобок вокруг нее (.*) , то в заменяющей части команды sed мы печатаем только захваченную группу, используя ее обратную ссылку.

Если вы используете zsh жизнь намного проще, просто используйте :h модификатор:

 $ var='dir/subdir/othersubdir/file.txt' $ echo "$var:h" dir/subdir/othersubdir