Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

This question already has an answer here:

Here is an example of file path:

/isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt

What I want to get is the file basename:

VMN CRTro.txt

So I try the following:

echo /isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt | sed s'/\// /g' | awk '{print $NF}'
CRTro.txt     <-- not as expected

Or

basename  /isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt
basename: extra operand `Doma'
Try `basename --help' for more information.     <-- basename cant handle spaces 

What the best way to get the basename of a file with spaces in it?

share|improve this question

marked as duplicate by Gilles Jul 29 at 22:04

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2  
what about basename "/isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt" –  rob Jul 29 at 12:30
2  
yes its so simple , I am really stupid!!!!!!!!!!!!!!! –  maihabunash Jul 29 at 12:32

3 Answers 3

up vote 15 down vote accepted

Just quote your path

basename  "/isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt"
share|improve this answer
    
WOW 14 points ! –  maihabunash Jul 29 at 15:52
1  
It was a very difficult question... –  dan3 Jul 29 at 19:32

The core of the issue is quoting. Without quotes, it's treating the file name as multiple arguments to basename.
If the path is hard set, and not a variable, then rob's answer is good. But if this is part of a script, where a variable is being used, you have 2 good solutions:

$ filepath="/isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt"
$ basename "$filepath"
VMN CRTro.txt

However basename is an external utility, and not part of bash. There is an alternative solution built into bash:

$ filepath="/isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt"
$ echo "${filepath##*/}"
VMN CRTro.txt

The ${filepath##*/} tells bash to perform the glob */, which matches as many characters as possible followed by a /, and then strip it out.

share|improve this answer
6  
The usual warning about basename vs ${var##*/}: it doesn't work properly for path/to/dir/ or /. You'd want basename -- "$filepath" (for paths that start with -). –  Stéphane Chazelas Jul 29 at 12:51

Both the answers here are more than sufficient - though I would personally do as Patrick suggests and use ${var##*/}. Still, just for fun:

IFS=/ ; set -f
set -- ${0+/isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt}
for p do i=$((i+1))
    printf "arg#$i:\t%s\n" "${p:-/}"
done
echo now shift out...
shift $(($#-1))
printf 'arg#1:\t%s\n' "$1"

OUTPUT

arg#1:  /
arg#2:  isf
arg#3:  GCM
arg#4:  VPfig
arg#5:  Aas
arg#6:  AR
arg#7:  ClCo el Doma Republic
arg#8:  VMN CRTro.txt
now shift out...
arg#1:  VMN CRTro.txt

You don't have to worry about $IFS eating up your variable evaluations if you set it properly. You can even use it to your advantage.

share|improve this answer
    
Note that the above doesn't work in bash (except in sh emulation) and you get an odd behaviour with mksh –  Stéphane Chazelas Jul 29 at 13:53
    
@StéphaneChazelas - I fixed it for bash - I guess it doesn't like variable declarations against builtins. Or maybe it doesn't persist them. Anyway, just added a semicolon. I don't have mksh though - I should probably install it. –  mikeserv Jul 29 at 14:06
    
It only worked because set is a special builtin. For mksh, see thread.gmane.org/gmane.os.miros.mksh/424 –  Stéphane Chazelas Jul 29 at 14:17
    
@StephaneChezales - I just installed it and I see what you mean - you get 7 arguments because the lone / is completely evaluated away. So $1 becomes isf - weird. Anyway, it does work, but it bothers me. 16 minutes ago huh? As always, thank you. –  mikeserv Jul 29 at 14:20
    
@StéphaneChazelas - about the bash thing. Also, while I've got your ear, in a manner of speaking, any idea what happens after interpretation approved? - it's added to the next version maybe? –  mikeserv Jul 29 at 14:51

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