59

I am trying to get "abc.txt" out of /this/is/could/be/any/path/abc.txt using Unix command. Note that /this/is/could/be/any/path is dynamic.

Any idea?

H. Pauwelyn
  • 13,575
  • 26
  • 81
  • 144
iwan
  • 7,269
  • 18
  • 48
  • 66

4 Answers4

87

In bash:

path=/this/is/could/be/any/path/abc.txt

If your path has spaces in it, wrap it in "

path="/this/is/could/be/any/path/a b c.txt"

Then to extract the path, use the basename function

file=$(basename "$path")

or

file=${path##*/}
Rodrigue
  • 3,617
  • 2
  • 37
  • 49
kev
  • 155,172
  • 47
  • 273
  • 272
  • 1
    `file=${path##*/}` will work in `ksh` as well; in fact, bash borrowed this feature from ksh. Any `sh` on any Linux system is likely to support this, too. – sorpigal Apr 12 '12 at 13:59
  • 2
    It should be enclosed in double quotes to avoid problems with funny characters in the file name: `file="$(basename $path)"` or `file="${path##*/}"` – Keith Thompson Jul 19 '14 at 18:58
  • You answer is good, but if the designer wants the script to work with paths that have space, the first answer needs quotation marks around the $path, so: file=${basename "$path"} . I've made an edit of the answer to fix that but I think it needs your approval. @Keith Thompson, file="${basename $path}" wouldn't work, the quotes need to be on $path or the basename function won't work properly. – thebunnyrules Jan 30 '18 at 09:32
  • This is really useful, and basename can remove file extensions as well. – Merlin Oct 10 '21 at 05:59
6

basename path gives the file name at the end of path

Edit:

It is probably worth adding that a common pattern is to use back quotes around commands e.g. `basename ...`, so UNIX shells will execute the command and return its textual value.

So to assign the result of basename to a variable, use

x=`basename ...path...`

and $x will be the file name.

gbulmer
  • 4,210
  • 18
  • 20
  • 1
    I've tried this and basename seems to be falling over on paths where there is a space in the name. – TimGJ Jul 19 '14 at 17:57
2

You can use basename /this/is/could/be/any/path/abc.txt

tonymarschall
  • 3,862
  • 3
  • 29
  • 52
2

You can use dirname command

$ dirname $path
  • That is the reverse what OP is asking for: `dirname any/path/abc.txt` -> `any/path`, while they were asking for `abc.txt` – Marcono1234 Feb 29 '20 at 17:31