Home > Software engineering >  Is it possible to combine bash variable search and replace with substring?
Is it possible to combine bash variable search and replace with substring?

Time:05-10

I have this function:

#! /usr/bin/env bash

function underline() {
  U="${1//?/${2:--}}"
  echo -e "\n$1\n${U:0:${#1}}\n"
}

underline "$1" "^-v-"

will work as expected:

$ ./u.sh "This is all you're going to see"

This is all you're going to see
^-v-^-v-^-v-^-v-^-v-^-v-^-v-^-v

It does what you expect. Originally it assumed that the underline character was just that, 1 character.

For "fun", I extended it to move from a single character underline to a repeating string underline (why? ... well ... because I can I suppose ... almost zero practical value in this exercise!).

And so, being the "let's make this so difficult that you need to write 2 pages of documentation to explain what's going on" sort of guy, I was wondering if the function could be written as a single line. And I don't mean:

function underline() { U="${1//?/${2:--}}"; echo -e "\n$1\n${U:0:${#1}}\n"; }

I don't think you can combine bash's variable search/replace with substring which is what is required.

I'm aware that this will work happily in zsh:

#! /usr/bin/env zsh

function underline() {
  echo -e "\n$1\n${${1//?/${2:--}}:0:${#1}}\n"
}

underline $1 "^-v-"

e.g.

$ ./u.sh "This is all you're going to see"

This is all you're going to see
^-v-^-v-^-v-^-v-^-v-^-v-^-v-^-v

but not capable of this in bash (it seems).

CodePudding user response:

No, you cannot combine those in a single parameter expansion in bash. But this single printf (a builtin in bash) should do the trick:

underline() { printf '%s\n%.*s\n' "$1" ${#1} "${1//?/${2:--}}"; }

underline "This is all you're going to see" "^-v-"

outputs

This is all you're going to see
^-v-^-v-^-v-^-v-^-v-^-v-^-v-^-v
  • Related