Здесь проблема в том, что вы окружаете переменную двойными кавычками (""). Удалите его, и все будет работать нормально.
VAR="This displays with \
extra spaces."
echo ${VAR}
Выход
This displays with extra spaces.
Здесь проблема в том, что двойная кавычка переменной сохраняет все символы пробела. Это может быть использовано в случае, если вам это явно необходимо.
Например,
$ echo "Hello World ........ ... ...."
распечатает
Hello World ........ ... ....
И на удаление цитаты, его разные
$ echo Hello World ........ ... ....
Hello World ........ ... ....
Здесь Bash удаляет лишние пробелы в тексте, потому что в первом случае весь текст воспринимается как «одиночный» аргумент и, таким образом, сохраняется лишние пробелы. Но во втором случае echo
команда получает текст в виде 5 аргументов.
Заключение в кавычки переменной также будет полезно при передаче аргументов командам.
В приведенной ниже команде echo
только получает один аргумент как"Hello World"
$ variable="Hello World"
$ echo "$variable"
Но в случае нижеприведенного сценария echo
получает два аргумента как Hello
иWorld
$ variable="Hello World"
$ echo $variable
$IFS
является мощным и универсальным инструментом, но код, написанный таким образом, никогда не сможет дать надежных результатов любого рода.*
?
[]
).Решения, предложенные esuoxu и Mickaël Bucas, являются распространенным и более портативным способом сделать это.
Вот несколько
bash
решений (некоторые из которых также должны работать в других оболочках, напримерzsh
). Во-первых, с помощью+=
оператора добавления (который работает немного по-разному для каждой из целочисленной переменной, регулярной переменной и массива).Если вам нужны новые строки (или другие пробелы / экранированные символы) в тексте, используйте
$''
вместо этого кавычки:Затем, используя,
printf -v
чтобы назначить форматированное значение переменнойХитрость заключается в том, что аргументов больше, чем спецификаторов формата, поэтому в отличие от большинства
printf
функций, bash повторно использует строку формата, пока не закончится. Вы можете поместить\n
внутри строки формата, или использовать $ '', (или оба) для работы с пробелами.Далее с помощью массива:
Вы также можете использовать
+=
для построения текста построчно (обратите внимание на()
):Здесь, однако, вы должны помнить, чтобы "сгладить" массив, если вы хотите, чтобы весь текстовый контент за один раз
(целочисленные индексированные массивы неявно сортируются, в отличие от ассоциативных массивов). Это дает вам немного больше гибкости, так как вы можете манипулировать линиями и даже вырезать и нарезать кубики, если это необходимо.
Наконец, используя
read
илиreadarray
и «здесь-документ»:Форма здесь-документа
<<-
означает, что все ведущие жесткие вкладки удаляются из ввода, поэтому вы должны использовать вкладки для отступа вашего текста. Кавычки"EOT"
не позволяют расширить возможности оболочки, поэтому ввод используется дословно. Приread
этом используется ввод с разделением байтов NUL, так что он будет читать текст с разделителями новой строки за один раз. С помощьюreadarray
(он жеmapfile
доступен с bash-4.0) он считывает в массив и-t
разбивает символы новой строки в каждой строке.источник
read
Вариант сhere document
очень приятно! Полезно для встраивания скриптов Python и выполнения сpython -c
. Я раньше делалscript=$(cat <here document>)
, ноread -r -d '' script <here document>
гораздо лучше.Существует специальный синтаксис heredoc, который удаляет вкладки в начале всех строк: «<< -» (обратите внимание на добавленную черту)
http://tldp.org/LDP/abs/html/here-docs.html
Пример 19-4. Многострочное сообщение с вкладками подавлено
Вы можете использовать это так:
Результат:
Работает только с вкладками, а не пробелами.
источник
\t
отлично работает, хотя, если вам нужны вкладки. Просто используйте,echo -e "$v"
а неecho "$v"
включайте символы обратной косой чертыПусть оболочка съест нежелательные переводы строки и следующие пробелы:
Так что это возможно ... но, конечно, дело вкуса, нравится или не нравится это решение ...
источник
Может быть, вы можете попробовать это.
источник
Вот как я предлагаю вам сделать это, и я объясню почему, но сначала я хочу поговорить о чем-то еще ...
Многие другие предлагаемые здесь решения, похоже, предполагают, что вы можете каким-то образом повлиять на содержимое переменной оболочки, изменив методы ее расширения. Уверяю вас, это не тот случай.
ВЫХОД
То, что вы видите выше, это сначала расширение с разделением полей, затем отчет о количестве байтов для исходной переменной расширения, затем расширение с разделителями кавычками и тот же счетчик байтов. Хотя выходные данные могут отличаться, содержимое переменной оболочки
$string
никогда не изменяется вообще, кроме как при присваивании.Более того, если вы не понимаете, почему это так, вы непременно столкнетесь с некоторыми очень неприятными сюрпризами раньше, чем позже. Давайте попробуем это снова, но в немного других условиях.
То же самое
$string
- другая среда.ВЫХОД
Разделение полей происходит на основе разделителей полей, определенных в
$IFS
. Есть два вида разделителей -$IFS
пробелы и$IFS
все остальное. По умолчанию$IFS
назначается новая строка на вкладке пробела - это три возможных$IFS
значения пробела. Однако, как вы можете видеть выше, его легко изменить, и он может оказать радикальное влияние на расщепление полей.$IFS
пробельные символы будут последовательно перемещаться в одно поле - и именно поэтомуecho
расширение, содержащее любую последовательность пробелов, если оно$IFS
содержит пробел, будет вычисляться только в один пробел - потому чтоecho
объединяет свои аргументы в пробелах. Но любые непробельные значения не будут вытесняться одинаково, и каждый встречающийся разделитель всегда получает поле для себя - как видно из раскрытия материала выше.Это не самое худшее. Считай это другим
$string
.ВЫХОД
Выглядит хорошо, верно? Что ж, давайте снова изменим окружающую среду.
ВЫХОД
Ого.
По умолчанию оболочка будет расширять глобусы имен файлов, если она может соответствовать им. Это происходит после раскрытия параметра и разделения поля в его порядке разбора, поэтому любая строка без кавычек уязвима в этом смысле. Вы можете отключить это поведение,
set -f
если хотите, но любая POSIX-совместимая оболочка всегда будет по умолчанию.Это тот тип вещей, с которым вы сталкиваетесь, когда выбрасываете кавычки в расширениях в соответствии со своими предпочтениями отступов. И даже в этом случае, в любом случае, независимо от его поведения расширения, фактическое значение для
$string
всегда остается таким, каким оно было при последнем назначении. Итак, вернемся к первому.ВЫХОД
Я считаю, что это гораздо более разумный способ адаптации синтаксиса оболочки к вашим предпочтениям отступов. То, что я делаю выше, - это назначение каждой отдельной строки позиционному параметру - на который можно ссылаться по номеру, например,
$1
или${33}
-, а затем присвоение их сцепленных значений с$var
помощью специального параметра оболочки$*
.Этот подход не застрахован от
$IFS
этого. Тем не менее, я считаю, что это связано с$IFS
дополнительным преимуществом в этом отношении. Рассмотреть возможность:ВЫХОД
Как видите,
$*
объединяет каждый аргумент в"$@"
первом байте$IFS
. Таким образом, при сохранении значения$IFS
по-разному назначаются разные разделители полей для каждого сохраненного значения. Между прочим, вы видите буквальное значение для каждой переменной. Если вы вообще не хотите использовать разделитель, вы должны сделать:ВЫХОД
источник
Вы можете попробовать:
или же
а также вы можете проверить это .
источник
Используйте расширение замещения Bash
Если вы используете Bash, вы можете использовать расширение замещения . Например:
источник
Это вариант для установки переменных типа пути:
Использование
set
перезаписей$@
, которые можно сохранить и использовать позже следующим образом:В
LD_LIBRARY_PATH=$(sed 's/ :/:/g' <<< $LD_LIBRARY_PATH)
линии Устраняет пространства перед двоеточием, а также возможно замыкающие пробелы. Если только устранение завершающих пробелов, используйтеLD_LIBRARY_PATH=${LD_LIBRARY_PATH%% }
вместо этого.Весь этот подход является вариантом превосходного ответа Mikeserv.
источник
Не бойтесь пробелов. Просто удалите их, прежде чем печатать многострочный текст.
Выход:
Нет необходимости использовать
<<-
heredoc и разбить отступ в 4 пробела символами табуляции.источник