Як вказати багаторядкову змінну оболонки?


122

Я написав запит:

function print_ui_hosts
{
local sql = "select ........."
print_sql "$ sql"
}

local sql - дуже довга струна. Запит не форматований. Як я можу розділити рядок на кілька рядків?


4
Про що shellтут добре говорити? Повинен batchбути bashчи ти справді з темного боку?
Кріс Сеймур

1
якщо це shell / bash, ви не повинні оточувати =пробіли.
Нік О'Лай

Відповіді:


138

Використовуйте readгередок, як показано нижче:

read -d '' sql << EOF
select c1, c2 from foo
where c1='something'
EOF

echo "$sql"

52
Зверніть увагу, що readу цій ситуації буде код виходу 1; якщо це має значення (ви працюєте з set -e, наприклад), ви хочете додати а || trueв кінці першого рядка.
чепнер

4
set -eвиходить із оболонки, якщо команда має "непередбачений" ненульовий статус виходу. Під "непередбачуваним" я маю на увазі, що він працює в контексті, коли ви конкретно не дивитесь на його вихідний статус. falseНаприклад, сам по собі вийшов би з оболонки. false || trueні, оскільки ви очікуєте ненульового стану виходу, вказавши іншу команду, яку потрібно запустити, якщо перша не вдасться.
чепнер

1
Проблема з set -e та read (див. Останню вправу) тут детально описана: mywiki.wooledge.org/BashFAQ/105
Niklas Peter

5
що -d ' 'тут роблять?
hg_git

3
@hg_git Говорячи readне зупиняти читання, коли зустрічаєте новий рядок.
Cyker

170

просто вставте новий рядок, де це необхідно

sql="
SELECT c1, c2
from Table1, Table2
where ...
"

оболонка буде шукати лапки, що закривається


7
не гарне рішення, якщо запит sql містить подвійні лапки. Вам доведеться уникати їх, і воно стане безладним.
dogbane

13
Подвійні цитати @dogbane зустрічаються рідко в більшості діалектів SQL, тому на практиці це чисто.
Ієн Самуель Маклін Старший

4
Потім оберніть рядок в одиничні лапки.
трійка

Не впевнений, чому ви хочете чи потребуєте розриву ведучої лінії. Для моєї заявки я цього не зробив, я тільки почав зsql="SELECT c2, c2
bhfailor

1
Смішно, що це здається занадто простим, щоб бути правдою. FYI, щоб додати DQ, просто створіть змінну DQ = '\ "', а потім
Тімоті К. Квін

69

Я хотів би дати одну додаткову відповідь, тоді як іншої буде достатньо в більшості випадків.

Я хотів написати рядок через кілька рядків, але його вміст повинен був бути однорядним.

sql="                       \
SELECT c1, c2               \
from Table1, ${TABLE2}      \
where ...                   \
"

Мені дуже шкода, якщо це трохи поза темою (мені це не потрібно для SQL). Однак ця публікація з’являється серед перших результатів під час пошуку багаторядкових змінних оболонок, і додаткова відповідь видалася доцільною.


1
Навіть без \ 'є мого вмісту виходить в одному рядку.
папіро

12
@papiro, спробуйте echo "$sql"замість echo $sql.
Майкл Мол

@MichaelMol - Близько двох десятиліть після моєї першої установки Linux, і я все ще дізнаюся щось нове. Дякуємо за цей «трюк».
Сет

6

Завдяки відповіді dimo414 на подібне запитання , це показує, як працює його чудове рішення, і показує, що ви також можете легко в тексті мати лапки та змінні:

Приклад виведення

$ ./test.sh

The text from the example function is:
  Welcome dev: Would you "like" to know how many 'files' there are in /tmp?

  There are "      38" files in /tmp, according to the "wc" command

test.sh

#!/bin/bash

function text1()
{
  COUNT=$(\ls /tmp | wc -l)
cat <<EOF

  $1 Would you "like" to know how many 'files' there are in /tmp?

  There are "$COUNT" files in /tmp, according to the "wc" command

EOF
}

function main()
{
  OUT=$(text1 "Welcome dev:")
  echo "The text from the example function is: $OUT"
}

main

5

readне експортує змінну (що є хорошою справою більшість часу). Ось альтернатива, яка може бути експортована в одній команді, може зберігати або відкидати канали ліній, а також дозволяє змішувати стилі котирування за потребою. Працює на bash і zsh.

oneLine=$(printf %s \
    a   \
    " b "   \
    $'\tc\t'    \
    'd '    \
)
multiLine=$(printf '%s\n' \
    a   \
    " b "   \
    $'\tc\t'    \
    'd '    \
)

Я визнаю, що необхідність цитування робить це некрасивим для SQL, але воно відповідає на (більш загальновиражений) питання в заголовку.

Я використовую це так

export LS_COLORS=$(printf %s    \
    ':*rc=36:*.ini=36:*.inf=36:*.cfg=36:*~=33:*.bak=33:*$=33'   \
    ...
    ':bd=40;33;1:cd=40;33;1:or=1;31:mi=31:ex=00')

у файлі, отриманому як з мого, так .bashrcі з .zshrc.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.