Substrings in zsh
23 Mar 2023To get only parts of a specific string in zsh, you can use the ${var:start:stop}
syntax.
If stop
is omitted, it will cut until the end of the string. You can also pass negative values.
To get only parts of a specific string in zsh, you can use the ${var:start:stop}
syntax.
If stop
is omitted, it will cut until the end of the string. You can also pass negative values.
To get the path of the folder of the script currently running in zsh, use ${0:a:h}
. $0
is the path to the currently running script, a
forces it to absolute, and h
to keep the head (the folder).
This is useful when you need to reference scripts that are not in your $PATH
, but are stored close to your initial script.
Trimming a string means removing any space at the beginning or end of it. It's something I need to do often when parsing the output of commands.
The easiest way I found to do it in zsh is to cast the string into an array, and back into a string with myvar="${=myVar}"
.
The ${=}
syntax splits the string as a list of arguments (so, separated by spaces), and wrapping it in ""
casts it back into a string.
One could use a similar trick by using echo " one two three " | xargs
, but this would require spawning a new process.
To get only part of a specific array in zsh, you have to use the [@]:X:Y
syntax, where X
is the start of your slice and Y
the end of it.
You can omit the Y
or use negative indices.
For example, ${myArray[@]:2}
slices the array by removing its first element
zsh doesn't have a way to check if a value is in an array, but can tell us (using ${(ie)}
) the index of the element.
The i
means i
nverse subscript, meaning that instead of accessing a value by its index, we want to access the index by its value.
e
is for e
xact match; without it zsh will return the index of any value that contains the substring, instead of exactly matching it.
The trick is that if the value is not found, zsh will return the length of the array + 1
.
So, to summarize, to check if the value zsh
is in the array myArray
, you would test it that way:
if [[ ${myArray[(ie)zsh]} -le ${#myArray} ]]; then
# ${#myArray} return the length of the array
fi
Alternatively, if the string you're looking for is dynamic ($myVar
), you'll need one more wrapping level: ${myArray[(ie)${myVar}]}
.
Edit: Thanks to Alan for fixing a typo.