Assuming that you are trying to find the filename portion of a Windows pathname containing backslashes...
pathname='Z:\201708021541\file name with spaces.123'
filename=$(basename "${pathname//\\//}")
printf '%s\n' "$filename"
This will print
file name with spaces.123
if run in bash
.
The parameter substitution ${pathname//\\//}
replaces all backslashes with forward slashes in the value of $pathname
, which means that the standard basename
utility can work on it. The basename
utility does not care that the path starts with Z:
(it believes that this is the name of a directory).
Alternatively (shorter, and more portable):
pathname='Z:\201708021541\file name with spaces.123'
filename=${pathname##*\\}
printf '%s\n' "$filename"
Here, ${pathname##*\\}
will remove everything up to the last backslash in $pathname
. This parameter substitution is standard, whereas the one used in the first variation will only work in certain shells.
Using awk
:
printf '%s\n' "$pathname" | awk '{ sub(".*\\\\", "", $0); print }'
The four backslashes are two backslashes escaped once each, because reasons.
Using sed
:
printf '%s\n' "$pathname" | sed 's/.*\\//'
Both the awk
and sed
solutions work exactly the same way. They substitute everything up to (and including) the last backslash with an empty string.
awk
or do you useawk
becausebasename
does not understand Windows paths? – Kusalananda Mar 07 '18 at 22:37