-
Notifications
You must be signed in to change notification settings - Fork 2
/
parse-path
executable file
·90 lines (77 loc) · 2.98 KB
/
parse-path
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/bin/bash
set -e
# Gokberk Cinbis, February 2020
# todo: add unit tests
help_mode=0
function print_example()
{
local p_="$1"
echo "<path> = $p_"
for opt_ in -fname -fname-noext -ext -path-noext -dir
do
echo " $opt_: `func-split-filename $opt_ $p_`"
done
}
function func-split-filename()
{
local narg=$#
local opt="$1"
local path="$2"
if [ $narg -ne 2 ]
then
if [ $helpmode = 1 ]; then
exit 3 # avoid recursion
fi
helpmode=1
echo "USAGE: parse-path <opt> <path>"
echo "Returns basepath, filename without extension, extension, etc. depending on <opt> for the file <path>"
echo "Input <path> is assumed to be a file path. Directory path inputs are not supported."
echo ""
echo "<opt> can be one of the following:"
echo " -fname Print filename without directory but with extension."
echo " -fname-noext Print filename without extension and without directory path."
echo " -ext Print extension. If file does not have an extension returns empty, otherwise, returns '.ext' (with dot prefix)."
echo " -path-noext Print file path without extension but with directory path."
echo " -dir Print directory path only. If non-empty, result is provided with the / suffix."
echo ""
echo "NOTES"
echo "* In a file with multiple dots, the very last one is considered as the extension."
echo "* Existance of the file or whether the given path is a file path or not is not checked."
echo "* UTF-8 filenames requires further testing."
echo
echo "EXAMPLES"
print_example "f.ext"
print_example "/a.b/x"
print_example "/a.b/x.y.z"
print_example "utf-8-test/şu-gülün/adı/değişse/bilé/jéan.txt"
exit 1
fi
local fname=$(basename "$path") # first remove the preceding path
# https://unix.stackexchange.com/questions/236029/bash-how-do-you-return-file-extensions?rq=1
case ${fname##*/} in
(?*.*) ext="."${fname##*.};; # add . prefix
(*) ext=;; # no extension, therefore empty
esac
local fname_noext=$(basename "$fname" "$ext") # first remove the preceding path
# Hard to handle with edge cases: local dir=$(dirname "$fname")
# dirname returns "." for both "./a" and "a"!
fnamelen=${#fname}
# remove the last fnamelen characters.
# works only in bash 4.2+ local dir=${path::-$fnamelen}
dir=${path}
for ((remove_index=0;remove_index<${fnamelen};remove_index++))
do
dir=${dir%?}
done
# assert: dir naturally contains / unless empty
case ${opt} in
("-fname") echo "$fname";;
("-fname-noext") echo "$fname_noext";;
("-ext") echo "$ext";;
("-path-noext") echo "$dir$fname_noext";;
("-dir") echo "$dir";;
(*) exit 2;; # better not print anything
esac
}
# ok with multiple quoted arguments
func-split-filename "$@"