My preferred terminal for daily use is fish. Quite
often I have to split a path and extract the filename from it. Unlike Bash, fish
does not have basename
utility. I use sed to extract the filename from the path.
It made sense to create a function so that I wouldn’t have to keep repeating the same regex.
Fish Function
1 2 3 |
|
- Line 1
-
Function name is
tm_split_path
. I prefer to prefix my shell functions with a common prefix. This way, I don’t have to recall the function name. I just typetm_
and presstab
key. Fish shell automatically suggests the list of possible functions.What follows
-d
is the description of the function. It appears in the list of suggestions. Notice the description in highlighted line in the following list. - Line 2
$argv
is the variable which contains the arguments passed to the function. It’s an array.
Remember
Array index in Fish starts from 1, not 0.
sed expression
I have written in detail about sed expression here.
Here is an example output,
$ echo "/User/talha/content/images/README.example.md" | sed 's/\(.*\)\/\(.*\)\.\(.*\)$/\1\n\2\n\3/'
README.example
md
/User/talha/content/images
Return Array
\n
in the replace pattern of sed expression is important. Each part of the
pathname is printed on the newline.
Fish automatically converts the input that has newlines into an array.
Create Array In Fish
- List every item on a new line
- Capture those lines in a command substitution
Now I can use the function, tm_split_path
, from other fish functions or scripts this way:
set result (tm_split_path "/Library/Extensions/File.kex")
echo Filename: $res[1]
echo Extensiion: $res[2]
echo Directory: $res[3]
(tm_split_path "/Library/Extensions/File.kex")
prints the filename, extension and directory, each on its own line.
set
assigns those three lines to result
variable.
Fish automatically assumes that the result is an array because of the new lines present.
This way, I can refer to filename, extension and, directory using array indices, like
$res[1]
for filename$res[2]
for extension$res[3]
for directory
Example
You can view complete script here.
This script also handles the case when the given argument does not have directory in it, like “filename.ext”.