Add prefix and suffix to $@ in bash

后端 未结 3 1172
孤街浪徒
孤街浪徒 2020-12-16 15:13

How to add suffix and prefix to $@?

If I do $PREFIX/$@/$SUFFIX, I get the prefix and the suffix only in the first parameter.

相关标签:
3条回答
  • 2020-12-16 15:49

    Let's create a parameters for test purposes:

    $ set -- one two three
    $ echo "$@"
    one two three
    

    Now, let's use bash to add prefixes and suffixes:

    $ IFS=$'\n' a=($(printf "pre/%s/post\n" "$@"))
    $ set -- "${a[@]}"
    $ echo -- "$@"
    pre/one/post pre/two/post pre/three/post
    

    Limitations: (a) since this uses newline-separated strings, it won't work if your $@ contains newlines itself. In that case, there may be another choice for IFS that would suffice. (b) This is subject to globbing. If either of these is an issue, see the more general solution below.

    On the other hand, if the positional parameters do not contain whitespace, then no change to IFS is needed.

    Also, if IFS is changed, then one may want to save IFS beforehand and restore afterward.

    More general solution

    If we don't want to make any assumptions about whitespace, we can modify "$@" with a loop:

    $ a=(); for p in "$@"; do a+=("pre/$p/post"); done
    $ set -- "${a[@]}"
    $ echo "$@"
    pre/one/post pre/two/post pre/three/post
    
    0 讨论(0)
  • 2020-12-16 16:15

    I would use shell [ parameter expansion ] for this

    $ set -- one two three
    $ echo "$@"
    one two three
    $ set -- "${@/#/pre}" && set -- "${@/%/post}"
    $ echo "$@"
    preonepost pretwopost prethreepost
    

    Notes

    • The # matches the beginning
    • The % matches the end
    • Using double quotes around ${@} considers each element as a separate word. so replacement happens for every positional parameter
    0 讨论(0)
  • 2020-12-16 16:15

    Note: This is essentially a slightly more detailed version of sjam's answer.

    John1024's answer is helpful, but:

    • requires a subshell (which involves a child process)
    • can result in unwanted globbing applied to the array elements.

    Fortunately, Bash parameter expansion can be applied to arrays too, which avoids these issues:

    set -- 'one' 'two' # sample input array, which will be reflected in $@
    
    # Copy $@ to new array ${a[@]}, adding a prefix to each element.
    # `/#` replaces the string that follows, up to the next `/`,
    # at the *start* of each element.
    # In the absence of a string, the replacement string following
    # the second `/` is unconditionally placed *before* each element.
    a=( "${@/#/PREFIX}" )
    
    # Add a suffix to each element of the resulting array ${a[@]}.
    # `/%` replaces the string that follows, up to the next `/`,
    # at the *end* of each element.
    # In the absence of a string, the replacement string following
    # the second `/` is unconditionally placed *after* each element.
    a=( "${a[@]/%/SUFFIX}" )
    
    # Print the resulting array.
    declare -p a
    

    This yields:

    declare -a a='([0]="PREFIXoneSUFFIX" [1]="PREFIXtwoSUFFIX")'
    

    Note that double-quoting the array references is crucial to protect their elements from potential word-splitting and globbing (filename expansion) - both of which are instances of shell expansions.

    0 讨论(0)
提交回复
热议问题