Объединение аргументов bash в одну строку с пробелами

41

Я пытаюсь объединить все аргументы функции Bash в одну строку с пробелами, разделяющими каждый аргумент. Мне также нужно, чтобы строка включала одинарные кавычки вокруг всей строки.

Вот что у меня так далеко ...

$array=("$@")
str="\'"
for arg in "${array[@]}"; do
    let $str=$str+$arg+" "
done
let $str=$str+"\'"

Очевидно, это не работает, но мне интересно, есть ли способ достичь этого?

Schwagmister
источник

Ответы:

58

Я считаю, что это делает то, что вы хотите. Все аргументы будут помещены в одну строку, разделенные пробелами, с одинарными кавычками:

str="'$*'"

$*создает все аргументы скрипта, разделенные первым символом, $IFSкоторый по умолчанию является пробелом.

Внутри строки в двойных кавычках нет необходимости экранировать одинарные кавычки.

пример

Давайте поместим вышеупомянутое в файл сценария:

$ cat script.sh 
#!/bin/sh
str="'$*'"
echo "$str"

Теперь запустите скрипт с примерами аргументов:

$ sh script.sh one two three four 5
'one two three four 5'

Этот скрипт POSIX. Это будет работать, bashно это не требует bash.

Вариант: конкатенация с косыми чертами вместо пробелов

Мы можем перейти от пробела к другому символу, настроив IFS:

$ cat script.sh 
#!/bin/sh
old="$IFS"
IFS='/'
str="'$*'"
echo "$str"
IFS=$old

Например:

$ sh script.sh one two three four       
'one/two/three/four'
John1024
источник
Хорошо, это работало отлично и делало именно то, что мне было нужно. Я пытаюсь использовать это, чтобы изменить каталог на каталог с пробелами в имени, просто используя аргументы. В конечном итоге я нуждался в том, чтобы создать функцию, которая будет изменять каталоги без необходимости вводить апострофы, если в каталоге есть слова, расположенные на расстоянии друг от друга. Я только что попробовал следующее: cdm () {str = "'$ *'" cd $ str} Получает доступ только к первому аргументу в str. Пример: cdm test 2 Результат: 'test: Нет такого файла или каталога
Schwagmister
@Schwagmister: Вы можете сохранить его в (строковую) переменную, если хотите, но, если вам это не нужно, я думаю, cd "$*"это будет достаточно хорошо.
Скотт
@Schwagmister Одиночные кавычки там не помогают. Попробуйте: cdm(){ str="$*"; cd "$str"; }или, как говорит Скотт cdm(){ cd "$*"; }. Также помните, что $*заменяет несколько последовательных пробелов одним пробелом. Если в имени вашего каталога может быть несколько последовательных пробелов, табуляции или новых строк, то эти символы действительно необходимо экранировать, прежде чем они будут переданы в cdmфункцию.
John1024
Так что, если это что-то вроде test 2 trial 1, как мне заставить эту команду cd работать правильно? Также это удивительная помощь, я действительно ценю это, ребята. @ Скотт
Швагмистер
@Schwagmister Лучший способ это поставить одинарные кавычки в командной строке при вызове , cdmкак в: cdm 'test 2 trial 1'. Это будет обрабатывать все поместье странных имен. Однако, если пробелы ограничены одиночными пробелами, cdmтогда он может быть запущен как cdm test 2 trial 1.
John1024
5

Это проще, чем вы думаете

#!/bin/bash
array="${@}"

echo $array

chmod + x и запустите:

$ ./example.sh --foo bar -b az 
--foo bar -b az
Клаату фон Шлакер
источник