shell - How to concatenate string variables in Bash

ID : 166

viewed : 119

Tags : bashshellsyntaxconcatstring-concatenationbash

Top 5 Answer for shell - How to concatenate string variables in Bash

vote vote

99

foo="Hello" foo="${foo} World" echo "${foo}" > Hello World 

In general to concatenate two variables you can just write them one after another:

a='Hello' b='World' c="${a} ${b}" echo "${c}" > Hello World 
vote vote

87

Bash also supports a += operator as shown in this code:

A="X Y" A+=" Z" echo "$A" 

output

X Y Z

vote vote

79

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 
vote vote

70

You can do this too:

$ var="myscript"  $ echo $var  myscript   $ var=${var}.sh  $ echo $var  myscript.sh 
vote vote

60

bla=hello laber=kthx echo "${bla}ohai${laber}bye" 

Will output

helloohaikthxbye 

This is useful when $blaohai leads to a variable not found error. Or if you have spaces or other special characters in your strings. "${foo}" properly escapes anything you put into it.

Top 3 video Explaining shell - How to concatenate string variables in Bash

Related QUESTION?