How to concatenate string variables in Bash

后端 未结 30 1547
攒了一身酷
攒了一身酷 2020-11-22 03:40

In PHP, strings are concatenated together as follows:

$foo = \"Hello\";
$foo .= \" World\";

Here, $foo becomes \"Hello World\"

相关标签:
30条回答
  • 2020-11-22 04:17

    Note that this won't work

    foo=HELLO
    bar=WORLD
    foobar=PREFIX_$foo_$bar
    

    as it seems to drop $foo and leaves you with:

    PREFIX_WORLD

    but this will work:

    foobar=PREFIX_"$foo"_"$bar"
    

    and leave you with the correct output:

    PREFIX_HELLO_WORLD

    0 讨论(0)
  • 2020-11-22 04:18

    Bash first

    As this question stand specifically for Bash, my first part of the answer would present different ways of doing this properly:

    +=: Append to variable

    The syntax += may be used in different ways:

    Append to string var+=...

    (Because I am frugal, I will only use two variables foo and a and then re-use the same in the whole answer. ;-)

    a=2
    a+=4
    echo $a
    24
    

    Using the Stack Overflow question syntax,

    foo="Hello"
    foo+=" World"
    echo $foo
    Hello World
    

    works fine!

    Append to an integer ((var+=...))

    variable a is a string, but also an integer

    echo $a
    24
    ((a+=12))
    echo $a
    36
    

    Append to an array var+=(...)

    Our a is also an array of only one element.

    echo ${a[@]}
    36
    
    a+=(18)
    
    echo ${a[@]}
    36 18
    echo ${a[0]}
    36
    echo ${a[1]}
    18
    

    Note that between parentheses, there is a space separated array. If you want to store a string containing spaces in your array, you have to enclose them:

    a+=(one word "hello world!" )
    bash: !": event not found
    

    Hmm.. this is not a bug, but a feature... To prevent bash to try to develop !", you could:

    a+=(one word "hello world"! 'hello world!' $'hello world\041')
    
    declare -p a
    declare -a a='([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="h
    ello world!" [6]="hello world!")'
    

    printf: Re-construct variable using the builtin command

    The printf builtin command gives a powerful way of drawing string format. As this is a Bash builtin, there is a option for sending formatted string to a variable instead of printing on stdout:

    echo ${a[@]}
    36 18 one word hello world! hello world! hello world!
    

    There are seven strings in this array. So we could build a formatted string containing exactly seven positional arguments:

    printf -v a "%s./.%s...'%s' '%s', '%s'=='%s'=='%s'" "${a[@]}"
    echo $a
    36./.18...'one' 'word', 'hello world!'=='hello world!'=='hello world!'
    

    Or we could use one argument format string which will be repeated as many argument submitted...

    Note that our a is still an array! Only first element is changed!

    declare -p a
    declare -a a='([0]="36./.18...'\''one'\'' '\''word'\'', '\''hello world!'\''=='\
    ''hello world!'\''=='\''hello world!'\''" [1]="18" [2]="one" [3]="word" [4]="hel
    lo world!" [5]="hello world!" [6]="hello world!")'
    

    Under bash, when you access a variable name without specifying index, you always address first element only!

    So to retrieve our seven field array, we only need to re-set 1st element:

    a=36
    declare -p a
    declare -a a='([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="he
    llo world!" [6]="hello world!")'
    

    One argument format string with many argument passed to:

    printf -v a[0] '<%s>\n' "${a[@]}"
    echo "$a"
    <36>
    <18>
    <one>
    <word>
    <hello world!>
    <hello world!>
    <hello world!>
    

    Using the Stack Overflow question syntax:

    foo="Hello"
    printf -v foo "%s World" $foo
    echo $foo
    Hello World
    

    Nota: The use of double-quotes may be useful for manipulating strings that contain spaces, tabulations and/or newlines

    printf -v foo "%s World" "$foo"
    

    Shell now

    Under POSIX shell, you could not use bashisms, so there is no builtin printf.

    Basically

    But you could simply do:

    foo="Hello"
    foo="$foo World"
    echo $foo
    Hello World
    

    Formatted, using forked printf

    If you want to use more sophisticated constructions you have to use a fork (new child process that make the job and return the result via stdout):

    foo="Hello"
    foo=$(printf "%s World" "$foo")
    echo $foo
    Hello World
    

    Historically, you could use backticks for retrieving result of a fork:

    foo="Hello"
    foo=`printf "%s World" "$foo"`
    echo $foo
    Hello World
    

    But this is not easy for nesting:

    foo="Today is: "
    foo=$(printf "%s %s" "$foo" "$(date)")
    echo $foo
    Today is: Sun Aug 4 11:58:23 CEST 2013
    

    with backticks, you have to escape inner forks with backslashes:

    foo="Today is: "
    foo=`printf "%s %s" "$foo" "\`date\`"`
    echo $foo
    Today is: Sun Aug 4 11:59:10 CEST 2013
    
    0 讨论(0)
  • 2020-11-22 04:18

    You can do this too:

    $ var="myscript"
    
    $ echo $var
    
    myscript
    
    
    $ var=${var}.sh
    
    $ echo $var
    
    myscript.sh
    
    0 讨论(0)
  • 2020-11-22 04:18

    The simplest way with quotation marks:

    B=Bar
    b=bar
    var="$B""$b""a"
    echo "Hello ""$var"
    
    0 讨论(0)
  • 2020-11-22 04:19

    Safer way:

    a="AAAAAAAAAAAA"
    b="BBBBBBBBBBBB"
    c="CCCCCCCCCCCC"
    d="DD DD"
    s="${a}${b}${c}${d}"
    echo "$s"
    AAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCDD DD
    

    Strings containing spaces can become part of command, use "$XXX" and "${XXX}" to avoid these errors.

    Plus take a look at other answer about +=

    0 讨论(0)
  • 2020-11-22 04:19

    If it is as your example of adding " World" to the original string, then it can be:

    #!/bin/bash
    
    foo="Hello"
    foo=$foo" World"
    echo $foo
    

    The output:

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