url=http://www.foo.bar/file.ext; echo ${url##/*}

I expected this code to print file.ext, but it prints the whole URL. Why? How can I extract the file name?

  • Okay obv I am expecting the wrong things to happen. Well I want to extract file.ext Commented Feb 11, 2013 at 14:41
  • You're trying to cut the end off the string? Try dirname $url. Or grep -o 'http://[^/]*' <<<$url.
    – Kevin
    Commented Feb 11, 2013 at 15:04

4 Answers 4


Because word has to match the string to be trimmed. It should look like:

$ url="http://www.foo.bar/file.ext"; echo "${url##*/}"

Thanks derobert, you steered me in the right direction. Further, as @frank-zdarsky mentioned, basename is in the GNU coreutils and should be available on most platforms as well.

$ basename "http://www.foo.bar/file.ext"
  • Hah, we both realize that at the same time. Glad to be of help.
    – derobert
    Commented Feb 11, 2013 at 14:51

To quote the manpage:

   Remove matching prefix pattern.  The word is expanded to produce
   a pattern just as in pathname expansion.  If the pattern matches
   the  beginning of the value of parameter, […]

/* does not match the beginning, because your URL starts with h not /.

A trivial way to do what you're looking for (according to your comment) is echo "$url" | rev | cut -d / -f 1 | rev. But of course, that'll give interesting results for URLs ending in a slash.

Another way to do what you want might be to use the pattern */ instead.

  • Glad you gave an explanation of what needs to be done and the quote from the manpage is a huge plus! That helped me a lot! Thanks again! :)
    – Fadi
    Commented Jul 12, 2017 at 14:45

basename(1) works with URLs, too, so you could simply do:

url=http://www.foo.bar/file.ext; basename $url

See also: Bash Extended Globbing, though in this case the extended glob is not essential.

 shopt -s extglob; url=http://www.foo.bar/file.ext; echo ${url##+(*/)}

Output: file.ext

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .