I have this variable, and I want to remove both prefix and suffix:

echo "${${var#a}%e}" 

I tried this snippet in zsh, and it works properly - returns bcd. It uses pattern matching (prefix and suffix). Although, when I run it in posix compliant shell script (the reason I'm using pattern matching instead of bash string manipulation), I get output bad substitution.

What is the matter? Must I make another variable to store "${var#a}" into or can I do it in one line? I want posix compliant script.


No, you do not need to have another variable, and yes, you can do it in a single line.

This is probably the most portable solution but it will overwrite the variable value (still using a single variable as mentioned in the question). It uses only parameter expansion of the shell language:

var="${var#a}" # remove prefix
echo "${var%e}" # remove suffix

One-liner may be always created as shown:

var="abcde"; var="${var#a}"; echo "${var%e}"

If you do not want to overwrite the variable, function arguments are perfect temporary variables. Although your example is trivial, you may create a function for it, which hides the extra variable used. This approach is especially useful since there are no local variables in the POSIX shell:

# this function runs in a subshell, so all new variables are lost on the return
remove_pre_post() (
    local_var="${1#a}" # uses the first argument
    echo "${local_var%e}"

remove_pre_post "$var" # call function

Another POSIX-compliant solution may involve sed:

echo "$var" | sed 's/^a//; s/e$//'

You provided only the example without any pattern matching. Keep in mind that once pattern matching is a thing, you may see one solution better than the other depending on the pattern complexity.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.