Problem statement: I want to extract an unknown string(last string) from a given path name in a single line command.


  1. The path is dynamic and can change with users input.
  2. Only last string is to be extracted using only one line o command.




In this case, I need to just extract the word tools.



In this again, I need to extact the last string cross

Is there a way to do this?

I tried to use cut command but it didn't work as the path length is dynamic.

  • 1
    What shell? at least in bash, you can do "${str##*/}" to remove the longest prefix matching */ from str. Or use basename. Jun 4 '16 at 13:41
  • I don't want to traverse to the directory and execute the the command. I want to extract the last string without traversing. Jun 4 '16 at 13:44
  • 1
    @steeldriver, ${parameter##word} is in all POSIX shells, (not just bash, see man dash ksh etc.).
    – agc
    Jun 4 '16 at 14:08
  • 1
    @AbhimanyuSaharan, suppose p=/home/xyz/Desktop/tools, run x="${p##*/}" to set $x to "tools", and echo $x to print "tools".
    – agc
    Jun 4 '16 at 14:17

I think basename is the command you are looking for.

[me@host ~]# basename /home/xyz/Desktop/tools

You can do that in bash and other shells without calling another program, which is of course much faster:

$ x=/home/xyz/Desktop/tools
$ echo ${x##*/}
$ y=/tmp/my_directory/my_big_dir/my_small/dir/cross
$ echo ${y##*/}

The ## removes the longest prefix it can find matching */

  • If you happen to have a path with a trailing slash (e.g. /foo/bar/), this will eat through to the final slash and return nothing. basename on the other hand seems to return the final component, i.e. bar
    – ilkkachu
    Jun 4 '16 at 16:35
  • I don't believe this is in POSIX, either, so if you're on some crappy platform where all you have is the plain-Jane Bourne shell (e.g. Debian unless you use a bash shebang), it won't work.
    – Kevin
    Jun 4 '16 at 19:45
  • @Kevin, Don't worry, it works in dash too. Even if it didn't, I suppose you did notice that the /bin/sh symlink can be changed.
    – ilkkachu
    Jun 4 '16 at 21:59
  • @ilkkachu: Fair enough, but changing the symlink is using global state to manage a local problem. The correct solution is to set an appropriate shebang line.
    – Kevin
    Jun 4 '16 at 22:09
  • @ilkkachu If the string has an (optional) ending /, then use: y=${y%/}; echo ${y##*/}
    – user79743
    Jun 6 '16 at 0:43
basename /your/full/path

Gives you the output that you want: path

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.