Як друкувати кожне слово, яке було повернуто з розширення оболонки на окрему рядок?

Коли ми використовуємо розширення оболонки, воно дає все розширене слово в одному рядку. Наприклад:

#!/bin/bash 
data="Hello\ {World,Rafi}"
eval echo $data

Це дає такий випуск:

Hello World Hello Rafi

Чи можна вивести кожен рядок на окрему рядок, як це?

Hello World 
Hello Rafi
3
Велике спасибі. Я так і не думав.
додано Автор Rafi Kamal, джерело
Ви тут не користуєтесь баш. eval є злом, особливо якщо ви не знаєте про його злість! Наприклад, якщо data = 'Hello; ls' , спробуйте eval echo "$ data" , у вас буде сюрприз. Тепер подумайте про те, що ls замінено на команду зла, наприклад, rm -rf. ... ви обов'язково повинні переосмислити свою стратегію!
додано Автор gniourf_gniourf, джерело

6 Відповіді

Якщо я правильно розумію вас, ви хочете створити кілька слів, використовуючи розширення ( {...} ), а потім надрукуйте кожне слово на окремому рядку.

Якщо вам не обов'язково потрібно зберігати в змінній "Hello \ (World, Rafi)" , ви можете зробити це за допомогою printf shell-builtin

printf "%s\n" "Hello "{Rafi,World}

Деяке пояснення:

Строка форматування (тут: % s \ n ) повторно використовується до тих пір, поки не буде використано всі аргументи printf ( Довідник ).

  1. %s\n consumes 1 argument
  2. "Hello "{Rafi,World} returns 2 words/arguments i.e. "Hello Rafi" and "Hello World"
  3. So, this printf command is equivalent to

    printf "%s\n%s\n" "Hello Rafi" "Hello World"
    

    except you don't have to type all that up.

5
додано
+1 для не з посиланням на eval .
додано Автор gniourf_gniourf, джерело

Same as Antarus'a answer, except that echo has "-n". From http://unixhelp.ed.ac.uk/CGI/man-cgi?echo

-n не виводить кінцеву нову лінію

#!/bin/bash
data="Hello\ {World,Rafi}'\n'"
eval echo -n -e "$data"
3
додано
#!/bin/bash
data="Hello\ {World'\n',Rafi'\n',Kamal'\n'}"
eval echo -e "$data"

echo -e will evaluate newline characters.

3
додано
Спасибі це працює :) Але він також друкує додатковий новий рядок в початку рядка, і якщо я переміщую нову лінію наприкінці ("Hello \ {World, Rafi} '\ n'", додатковий пробіл буде додано з друга лінія і далі .. чи є якийсь обхід?
додано Автор Rafi Kamal, джерело
@Rafi я відредагував відповідь. до кінця кожного слова додано новий символ рядка. пропустити додавання, якщо ви не хочете цього.
додано Автор Antarus, джерело

Насправді, ваша проблема - не розширення, а команда echo . Залежно від вашої системи, ви можете отримати те, що ви хочете

#!/bin/bash
data="Hello\ {World\\\\n,Rafi}"
eval echo -e "$data"
1
додано

Instead of using eval (which is dangerous and really not a good practice — see my comment in your post), another strategy would be to use an array. The following will do exactly what you want, in a clean and safe way:

data=( "Hello "{World,Rafi} )
printf "%s\n" "${data[@]}"
1
додано

Це інше рішення, але дуже чисте.

#!/bin/bash

names="World Rafi"
for name in $names
do
    echo Hello $name
done
1
додано
Або навіть для імені в {World, Rafi}; робити ...
додано Автор glenn jackman, джерело
+1 для не з посиланням на eval .
додано Автор gniourf_gniourf, джерело