Bash first
Поскольку этот вопрос обозначает специально Bash , моя первая часть ответа будет содержать различные способы сделать это правильно:
+=
:Добавить к переменной
Синтаксис +=
можно использовать по-разному:
Добавить к строке var+=...
(Поскольку я скромныйЯ буду использовать только две переменные foo
и a
, а затем повторно использовать их во всем ответе.; -)
a=2
a+=4
echo $a
24
Использование синтаксиса переполнения стека ,
foo="Hello"
foo+=" World"
echo $foo
Hello World
отлично работает!
Добавить к целому числу ((var+=...))
Переменная a
- это строка, но также целое число
echo $a
24
((a+=12))
echo $a
36
Добавить в массив var+=(...)
Наш a
также является массивом только из одного элемента.
echo ${a[@]}
36
a+=(18)
echo ${a[@]}
36 18
echo ${a[0]}
36
echo ${a[1]}
18
Обратите внимание, что между скобками есть пробел разделенный массив .Если вы хотите сохранить строку, содержащую пробелы в вашем массиве, вы должны заключить их:
a+=(one word "hello world!" )
bash: !": event not found
Хмм .. это не ошибка, а функция ... КомуДля того, чтобы bash не пытался разработать !"
, вы можете:
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
: пересоздать переменную с помощью встроенной команды
printf
встроенная команда дает мощный способ рисования формата строки.Поскольку это Bash встроенный , существует возможность отправки отформатированной строки в переменную вместо печати на stdout
:
echo ${a[@]}
36 18 one word hello world! hello world! hello world!
Существует семь строк в этом массиве.Таким образом, мы могли бы создать отформатированную строку, содержащую ровно семь позиционных аргументов:
printf -v a "%s./.%s...'%s' '%s', '%s'=='%s'=='%s'" "${a[@]}"
echo $a
36./.18...'one' 'word', 'hello world!'=='hello world!'=='hello world!'
Или мы могли бы использовать строку формата с одним аргументом , которая будет повторяться столько же, сколько передано аргумента ...
Обратите внимание, что наш a
по-прежнему является массивом!Изменен только первый элемент!
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!")'
В bash, когда вы обращаетесь к имени переменной без указания индекса, вы всегда обращаетесь только к первому элементу!
Итак, чтобы получить наш массив из семи полей, мынужно только переустановить 1-й элемент:
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!")'
Одна строка формата аргумента со многими аргументами, переданными:
printf -v a[0] '<%s>\n' "${a[@]}"
echo "$a"
<36>
<18>
<one>
<word>
<hello world!>
<hello world!>
<hello world!>
Использование Вопрос переполнения стека синтаксис:
foo="Hello"
printf -v foo "%s World" $foo
echo $foo
Hello World
Примечание: использование двойных кавычек может быть полезно для работы со строками, которые содержат spaces
, tabulations
и / или newlines
printf -v foo "%s World" "$foo"
Оболочка теперь
Под POSIX оболочкой нельзя использовать bashisms , поэтому нет встроенных printf
.
В основном
Но вы можете просто сделать:
foo="Hello"
foo="$foo World"
echo $foo
Hello World
Отформатировано, используя разветвленный printf
Если вы хотите использоватьболее сложные конструкции, вам нужно использовать fork (новый дочерний процесс, который выполняет задание и возвращает результат через stdout
):
foo="Hello"
foo=$(printf "%s World" "$foo")
echo $foo
Hello World
Исторически сложилось, что backticks можно было использовать для получения результата fork :
foo="Hello"
foo=`printf "%s World" "$foo"`
echo $foo
Hello World
Но это не так просто для nesting :
foo="Today is: "
foo=$(printf "%s %s" "$foo" "$(date)")
echo $foo
Today is: Sun Aug 4 11:58:23 CEST 2013
с обратными галочками, вы должны покинуть внутренние вилки с обратной косой чертой :
foo="Today is: "
foo=`printf "%s %s" "$foo" "\`date\`"`
echo $foo
Today is: Sun Aug 4 11:59:10 CEST 2013