Ось як я пропоную вам це зробити, і я поясню чому, але спершу я хочу поговорити про щось інше ...
set -- 'Arg 1: Line 1.' \
'Arg 2: Line 2.' \
'and so on for' \
'as long as you might like.'
var="$*"
Багато інших запропонованих тут рішень начебто підказують, що ви можете якось вплинути на вміст змінної оболонки, змінивши свої методи розширення. Можу запевнити, що це не так.
string="some stuff here \
some more stuff here."
echo $string ${#string}
echo "$string" "${#string}"
ВИХІД
some stuff here some more stuff here. 53
some stuff here some more stuff here. 53
Те, що ви бачите вище, - це спочатку розширення за розбиттям по полях, потім звіт про кількість байтів для вихідної змінної розширення, потім розширення з обмеженнями цитатами і те саме підрахунок байтів. Хоча вихід може відрізнятися, вміст змінної оболонки $stringвзагалі ніколи не змінюється, за винятком присвоєння.
Більше того, якщо ви не розумієте, чому це так, швидше за все ви зіткнетеся з дуже неприємними сюрпризами. Спробуємо це ще раз, але в дещо інших умовах.
IFS=sf
echo $string ${#string}
echo "$string" "${#string}"
Те саме $string- різне середовище.
ВИХІД
ome tu here ome more tu here. 53
some stuff here some more stuff here. 53
Розщеплення поля відбувається на основі роздільників поля, визначених у $IFS. Існує два види роздільників - $IFSпробіл та $IFSвсе інше. За замовчуванням $IFSпризначається вкладка$IFS пробілу значень newline - це три можливі значення пробілу. Це легко змінюється, хоча, як ви бачите вище, і може мати різкий вплив на розширення по полях.
$IFSпробіл буде витікати послідовно в одне поле - і саме тому echoрозширення, що містить будь-яку послідовність пробілів, коли $IFSмістить пробіл, буде оцінюватися лише на один простір, тому що echoоб'єднує свої аргументи на простори. Але будь-які значення, що не мають пробілу, не зміщуватимуться однаково, і кожен зустрічається роздільник завжди отримує поле для себе - як це видно з розширення матеріалів вище.
Це не найгірше. Розглянемо це інше $string.
IFS=$space$tab$newline
cd emptydir
string=" * * * \
* * * "
echo $string ${#string}
echo "$string" "${#string}"
ВИХІД
* * * * * * 30
* * * * * * 30
Виглядає нормально, правда? Що ж, давайте ще раз змінити середовище.
touch file1 file2 file3 file4 file5
echo $string ${#string}
echo "$string" "${#string}"
ВИХІД
file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 30
* * * * * * 30
Вуа.
За замовчуванням оболонка розширить кулі імен файлів, якщо вони можуть відповідати їм. Це відбувається після розширення параметра та розбиття поля в його порядку розбору, тому будь-яка не котирувана рядок є вразливою таким чином. Ви можете вимкнути цю поведінку, set -fякщо хочете, але будь-яка сумісна з POSIX оболонка завжди буде глобальною за замовчуванням.
Це та річ, проти якої ви ставитесь, коли ви кидаєте котирування на розширення відповідно до ваших переваг відступу. І навіть у будь-якому випадку, незалежно від поведінки щодо розширення, фактичне значення $stringзавжди залишається таким, яким воно було, коли ви востаннє присвоювали його. Тож повернемось до першого.
set -- 'Arg 1: Line 1.' \
'Arg 2: Line 2.' \
'and so on for' \
'as long as you might like.'
var="$*"
echo "$var" "${#var}"
ВИХІД
Arg 1: Line 1. Arg 2: Line 2. and so on for as long as you might like. 70
Я вважаю, що це набагато безпечніший спосіб адаптувати синтаксис оболонки до ваших уподобань. Я роблю вище - присвоюю кожній окремій рядку позиційний параметр, який може посилатися на номер типу $1або ${33}-, а потім присвоювати їх об'єднані значення за $varдопомогою спеціального параметра оболонки $*.
Цей підхід не застрахований від $IFSцього. І все-таки я вважаю її відношення до $IFSдодаткової вигоди в цьому відношенні. Поміркуйте:
IFS=\ ;space_split="$*"
IFS=/; slash_split="$*";IFS='
';new_line_split="$*"
echo "$space_split"
echo "$slash_split"
echo "$new_line_split"
ВИХІД
Arg 1: Line 1. Arg 2: Line 2. and so on for as long as you might like.
Arg 1: Line 1./Arg 2: Line 2./and so on for/as long as you might like.
Arg 1: Line 1.
Arg 2: Line 2.
and so on for
as long as you might like.
Як бачите, $*об'єднайте кожен аргумент у "$@"перший байт в $IFS. Таким чином, збереження його значення, а $IFSінше призначається, отримує різні роздільники поля для кожного збереженого значення. До речі, те, що ви бачите вище - це буквальне значення для кожної змінної. Якби ви взагалі не хотіли розмежувача, зробите:
IFS=;delimitless="$*"
echo "$delimitless" "${#delimitless}"
ВИХІД
Arg 1: Line 1.Arg 2: Line 2.and so on foras long as you might like. 67