Как вывести многострочную строку в Bash?
Как я могу вывести многострочную строку в Bash без использования нескольких эхо-вызовов, например, так:
echo "usage: up [--level <n>| -n <levels>][--help][--version]"
echo
echo "Report bugs to: "
echo "up home page: "
Я ищу портативный способ сделать это, используя только встроенные функции Bash.
Ответы
Ответ 1
Здесь документы часто используются для этой цели.
cat << EOF
usage: up [--level <n>| -n <levels>][--help][--version]
Report bugs to:
up home page:
EOF
Они поддерживаются во всех производных от Bourne оболочек, включая все версии Bash.
Ответ 2
или вы можете сделать это:
echo "usage: up [--level <n>| -n <levels>][--help][--version]
Report bugs to:
up home page: "
Ответ 3
Так как я рекомендовал printf
в комментарии, я должен, вероятно, привести некоторые примеры его использования (хотя для печати сообщения об использовании я с большей вероятностью воспользуюсь ответами Денниса или Криса). printf
немного сложнее в использовании, чем echo
. Его первым аргументом является строка формата, в которой escape-последовательности (например, \n
) всегда интерпретируются; он также может содержать директивы формата, начиная с %
, которые определяют, где и как любые дополнительные аргументы включены в него. Вот два разных подхода к использованию для сообщения об использовании:
Сначала вы можете включить все сообщение в строку формата:
printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: \nup home page: \n"
Обратите внимание, что в отличие от echo
, вы должны явно указать окончательную новую строку. Кроме того, если сообщение содержит какие-либо символы %
, они должны быть записаны как %%
. Если вы хотите включить адреса bugreport и домашнюю страницу, их можно добавить совершенно естественно:
printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: %s\nup home page: %s\n" "$bugreport" "$homepage"
Во-вторых, вы можете просто использовать строку формата, чтобы он печатал каждый дополнительный аргумент в отдельной строке:
printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: " "up home page: "
С помощью этой опции добавление адресов bugreport и домашней страницы довольно очевидно:
printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: $bugreport" "up home page: $homepage"
Ответ 4
Используйте параметр -e
, затем вы можете напечатать новый символ строки с \n
в строке.
Пример (но не уверен, хороший или нет)
Самое интересное, что опция -e
не документирована в странице руководства MacOS, пока она еще доступна. Он задокументирован на странице Linux.
Ответ 5
Вдохновленный проницательными ответами на этой странице, я создал смешанный подход, который я считаю самым простым и более гибким. Как вы думаете?
Во-первых, я определяю использование в переменной, что позволяет мне использовать его в разных контекстах. Формат очень прост, почти WYSIWYG, без необходимости добавлять какие-либо управляющие символы. Это кажется мне достаточно портативным (я запускал его на MacOS и Ubuntu)
__usage="
Usage: $(basename $0) [OPTIONS]
Options:
-l, --level <n> Something something something level
-n, --nnnnn <levels> Something something something n
-h, --help Something something something help
-v, --version Something something something version
"
Тогда я могу просто использовать его как
echo "$__usage"
или, что еще лучше, при разборе параметров я могу просто отобразить его там в одну строку:
levelN=${2:?"--level: n is required!""${__usage}"}
Ответ 6
Также с исходным кодом с отступом вы можете использовать <<-
(с завершающей чертой), чтобы игнорировать начальные вкладки (но не начальные пробелы). Например это:
if [ some test ]; then
cat <<- xx
line1
line2
xx
fi
Выводит текст с отступом без пробела:
line1
line2