Не завершающие символы новой строки не удаляются
Новые строки, которые вы ищете, есть, вы их просто не видите, потому что вы используете echo
без кавычек для переменной.
Проверка:
$ a=$( df -H )
$ echo $a
Filesystem Size Used Avail Use% Mounted on /dev/sda3 276G 50G 213G 19% / udev 2.1G 4.1k 2.1G 1% /dev tmpfs 832M 820k 832M 1% /run none 5.3M 0 5.3M 0% /run/lock none 2.1G 320k 2.1G 1% /run/shm
$ echo "$a"
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 276G 50G 213G 19% /
udev 2.1G 4.1k 2.1G 1% /dev
tmpfs 832M 820k 832M 1% /run
none 5.3M 0 5.3M 0% /run/lock
none 2.1G 320k 2.1G 1% /run/shm
$
Завершающие символы новой строки удалены.
Как правильно указал @ user4815162342, хотя новые строки в выводе не удаляются, завершающие новые строки удаляются с заменой команды. См. Эксперимент ниже:
$ a=$'test\n\n'
$ echo "$a"
test
$ b=$(echo "$a")
$ echo "$b"
test
$
В большинстве случаев это не имеет значения, потому что echo
добавит удаленную новую строку (если она не вызывается с параметром -n
), но есть некоторые крайние случаи, когда в выводе программы есть более одного завершающего символа новой строки, и они важно по какой-то причине.
Обходные пути
1. Добавьте фиктивный символ
В этом случае, как упоминалось в @Scrutinizer, вы можете использовать следующий обходной путь:
$ a=$(printf 'test\n\n'; printf x); a=${a%x}
$ echo "$a"
test
$
Пояснение: символ x
добавляется к выводу (с использованием printf x
) после новой строки. Поскольку новые строки больше не завершающие, они не удаляются при подстановке команд. Следующим шагом будет удаление добавленного нами x
с помощью оператора %
в ${a%x}
. Теперь у нас есть исходный результат со всеми символами новой строки !!!
2. Прочтите, используя подстановку процесса
Вместо использования подстановки команд для присвоения выходных данных программы переменной, мы можем вместо этого использовать подстановка процесса для передачи вывода программы во встроенную команду read
(указана ссылка на @ormaaj). Замена процесса сохраняет все новые строки. Чтение вывода в переменную немного сложно, но вы можете сделать это так:
$ IFS= read -rd '' var < <( printf 'test\n\n' )
$ echo "$var"
test
$
Пояснение:
- Мы устанавливаем внутренний разделитель полей для команды чтения в нуль, с
IFS=
. В противном случае read
не будет назначать var
весь вывод, а только первый токен.
- Мы вызываем
read
с параметрами -rd ''
. r
предназначен для предотвращения того, чтобы обратная косая черта действовала как специальный символ, а с d ''
установить разделитель на ноль, так что read считывает весь вывод, а не только первую строку.
3. Читать с трубы
Вместо использования подстановки команд или процессов для присвоения выходных данных программы переменной, мы можем передать выходные данные программы команде read
(указана @ormaaj). Конвейер также сохраняет все символы новой строки. Однако обратите внимание, что на этот раз мы установили необязательное поведение оболочки lastpipe
, используя встроенная shopt
. Это необходимо, чтобы команда read
выполнялась в текущей среде оболочки. В противном случае переменная будет назначена в подоболочке и не будет доступна из остальной части скрипта.
$ cat test.sh
#!/bin/bash
shopt -s lastpipe
printf "test\n\n" | IFS= read -rd '' var
echo "$var"
$ ./test.sh
test
$
person
user000001
schedule
03.03.2013
eval
. - person enharmonic   schedule 16.12.2020