0

I am trying to output parts of a file path but remove the file name and some levels of the path.

Currently I have a for loop doing a lot of things, but I am creating a variable from the full file path and would like to strip some bits out.

For example

for f in (find /path/to/my/file - name *.ext)

will give me

$f = /path/to/my/file/filename.ext

What I want to do is printf/echo some of that variable. I know I can do:

printf ${f#/path/to/}
my/file/filename.ext

But I would like to remove the filename and end up with:

my/file

Is there any easy way to do this without having to use sed/awk etc?

  • Possible duplicate of [Get file directory path from filepath](http://stackoverflow.com/questions/6121091/get-file-directory-path-from-filepath) – Benjamin W. Feb 26 '16 at 06:20
  • Try `${f%/*}` to remove the filename only (similar to the `dirname` builtin). (You should make sure there is more that 1 `/` before the removal or check for a zero-length after) – David C. Rankin Feb 26 '16 at 06:29

1 Answers1

1

When you know which level of your path you want, you can use cut:

echo "/path/to/my/filename/filename.ext" | cut -d/ -f4-5

When you want the last two levels of the path, you can use sed:

echo "/path/to/my/file/filename.ext" | sed 's#.*/\([^/]*/[^/]*\)/[^/]*$#\1#'

Explanation:

s/from/to/ and s#from#to# are equivalent, but will help when from or to has slashes.
s/xx\(remember_me\)yy/\1/ will replace "xxremember_meyy" by "remember_me"
s/\(r1\) and \(r2\)/==\2==\1==/ will replace "r1 and r2" by "==r2==r1=="
.* is the longest match with any characters
[^/]* is the longest match without a slash
$ is end of the string for a complete match
Walter A
  • 16,400
  • 2
  • 19
  • 36