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.
1 2 3
function tm_split_path -d 'Return filename, ext, and directory from the path' echo $argv | sed 's/\(.*\)\/\(.*\)\.\(.*\)$/\2\n\3\n\1/' end
- 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 type
tabkey. Fish shell automatically suggests the list of possible functions.
-dis the description of the function. It appears in the list of suggestions. Notice the description in highlighted line in the following list.
- Line 2
$argvis the variable which contains the arguments passed to the function. It’s an array.
Array index in Fish starts from 1, not 0.
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
\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 echo Extensiion: $res echo Directory: $res
(tm_split_path "/Library/Extensions/File.kex") prints the filename, extension and directory, each on its own line.
set assigns those three lines to
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
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”.
So what do you think? Did I miss something? Is any part unclear?
Leave your comments below.
You need a free Github account to comment.