Подтвердить что ты не робот

Петля над множеством строк, содержащих пробелы

У меня есть несколько строк типа "a b", "c d", "foo bar" и так далее. Я хочу перебрать этот набор строк и выполнить действие для каждого из них. В этом действии я вызываю несколько других скриптов, поэтому я не хочу менять IFS для этого цикла, так как он может нарушить мой вызов других скриптов. Вот почему я стараюсь избегать пространств, содержащихся в этих строках, но безуспешно.

Так, например, я ожидаю получить

a b
c d

И я попробовал следующее:

#!/bin/sh

x="a b"
y="c d"

echo "Attempt 1"
all="$x $y"

for i in $all ; do
  echo $i
done

echo "Attempt 2"
all="a\ b c\ d"
for i in $all ; do
  echo $i
done

echo "Attempt 3"
all=($x $y)
for i in ${all[@]} ; do
  echo $i
done

echo "Attempt 4"
all='"'$x'" "'$y'"'
for i in $all ; do
  echo $i
done

echo "Attempt 5"
for i in "$x" "$y" ; do
  echo $i
done

echo "Attempt 6"
all2=("a b" "c d");
for i in ${all2[@]}; do
  echo $i
done

echo "Attempt 7"
all3="a b c d"
echo $all3|
while read i; do
  echo $i 
done 

Только попытка 5 выполнена успешно, но я хотел бы сделать это, не указывая одну переменную на строку (было бы больно поддерживать). Я просто представил x и y для тестирования, но идея состоит в том, чтобы объявить в одной переменной набор "a b" и "c d".

4b9b3361

Ответ 1

Вам нужно обернуть переменные в двойные кавычки, как в all=("$x" "$y"), так и "${all[@]}":

x="a b"
y="c d"

echo "Attempt XX"
all=("$x" "$y")
for i in "${all[@]}" ; do
  echo "$i"
done

Выполнение этого возврата:

Attempt XX
a b
c d

Update

Чтобы избежать использования переменной для каждой строки, выполните следующие действия:

all=("a b" "c d")
for i in "${all[@]}" ; do
  echo "$i"
done

Ответ 2

Ваша проблема заключается в отсутствии цитирования. Без цитирования происходит разбиение слов:

$ x="a b"; y="c d"; all=("$x" "$y"); for i in "${all[@]}"; do echo "$i"; done
a b
c d

Использование массива является самым изящным решением, и, конечно, x и y являются излишними. Вы можете так же хорошо:

$ all=("a b" "c d"); for i in "${all[@]}"; do echo "$i"; done
a b
c d