2

I have a string which looks something like this

dir/subdir/othersubdir/file.txt

But it can also look like

dir/file.txt

or

dir/subdir/file.txt

Now, I am making a script where $P is the full path to the directory were file.txt is.

Now I use this

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

To be replace anything that ends with txt and comes after a /. This works fine when there is something like dir/file.txt, but not any of my other examples. How can I fix so that it matches what I want?

I don't want to match any subdirectories before .*txt. I want to remove only the file base name.

2
4

If you don't insist on using sed then you could consider using 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
2
  • Lol, there is an actual dedicated command to this, thanks. Dec 6 '14 at 21:13
  • @DisplayName - yes, and if you want the opposite (just the filename without the path) you can use the basename command. Dec 6 '14 at 21:15
2

Here is sed command:

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

In above sed command we capture anything.* from beginning^ of variable P that ends$ with/*.txt, which it's known as a captured group with\1 as its beck-reference because used a pair of parentheses around it(.*), then in replacement part of sed command, we prints only captured group by using its back-reference.

0
0

If you are using zsh life is much simpler, just use :h modifier:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.