Ітерація над рядковим рядком, що зберігається у змінній


17

Я читав, що погано писати такі речі for line in $(command), як здається, правильно замість цього:

command | while IFS= read -r line; do echo $line; done

Це чудово працює. Але що робити, якщо те, що я хочу повторити, це вміст змінної , а не прямий результат команди?

Наприклад, уявіть, що ви створюєте такий файл quickfox:

The quick brown
foxjumps\ over -
the
lazy ,
dog.

Я хотів би мати можливість зробити щось подібне:

# This is just for the example,
# I could of course stream the contents to `read`
variable=$(cat quickfox);
while IFS= read -r line < $variable; do echo $line; done; # this is incorrect

Відповіді:


19

У таких сучасних оболонках, як bash та zsh, у вас є дуже корисний переносник `<<< ', який приймає рядок як вхідний. Так ви зробили б

while IFS= read -r line ; do echo $line; done <<< "$variable"

Інакше завжди можна зробити

echo "$variable" | while IFS= read -r line ; do echo $line; done

Вибачте, я мав би подумати про повторення змісту. Але дякую за швидку відповідь все одно!
Шельон

1
$variableпри використанні його потрібно подвоїти цитування , інакше whileцикл отримає лише один рядок введення. Дивіться, наприклад, різниця у виході між echo $variableпроти echo "$variable"або cat <<< $variableпроти cat <<< "$variable".
cas

@cas Насправді це залежить від того, що знаходиться всередині змінної $. У випадку, представленому OP ("змінна = $ (cat quickfox)"), вона працює без додаткових лапок. Але для загального випадку ви маєте рацію. Я редагую свою відповідь. Спасибі.
lgeorget

У variable=$(cat quickfox)самому питанні щодо ОП наведено приклад того, про що я говорив. Використання $variableвнутрішніх подвійних лапок включає в себе нові рядки, використовуючи їх без перекладених оболонок новими рядками в пробіли. Якщо ви читаєте та обробляєте по черзі, це має величезну різницю - для першого ви маєте кілька рядків введення, а для другого - лише один рядок введення. Вхідні дані поверхнево схожі, але на практиці абсолютно різні в цих двох випадках.
cas

Наприклад: із цими вхідними даними cat <<< "$variable" | wc -lповертається 5. cat <<< $variable | wc -lповертається 1. Якщо ви хочете / потребуєте збереження пробілу (включаючи нові рядки, вкладки, одинарний чи декілька пробілів) у змінній, тоді Ви ОБОВ'ЯЗКОВО подвійно цитувати цю змінну при використанні її, інакше всі вони будуть перетворені в єдиний пробіл між кожним "словом".
cas
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.