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

Петля через переменную оболочки, разделенную запятой

Предположим, что у меня есть переменная оболочки Unix, как показано ниже

variable=abc,def,ghij

Я хочу извлечь все значения (abc, def и ghij) с помощью цикла for и передать каждое значение в процедуру.

script должен разрешить извлечение произвольного количества разделенных запятыми значений из $variable.

4b9b3361

Ответ 1

Вы можете использовать следующий script, чтобы динамически перемещаться по вашей переменной, независимо от того, сколько полей оно имеет, если оно только разделено запятой.

variable=abc,def,ghij
for i in $(echo $variable | sed "s/,/ /g")
do
    # call your procedure/other scripts here below
    echo "$i"
done

Вместо вызова echo "$i" выше, между do и done внутри цикла for вы можете вызвать свою процедуру proc "$i".


Обновление: приведенный выше фрагмент работает, если значение переменной не содержит пробелов. Если у вас есть такое требование, используйте одно из решений, которое может изменить IFS, а затем проанализировать вашу переменную.


Надеюсь, что это поможет.

Ответ 2

Не возиться с IFS
Не вызывать внешнюю команду

variable=abc,def,ghij
for i in ${variable//,/ }
do
    # call your procedure/other scripts here below
    echo "$i"
done

Использование bash манипуляции с строкой http://www.tldp.org/LDP/abs/html/string-manipulation.html

Ответ 3

Если вы установите другой разделитель полей, вы можете напрямую использовать цикл for:

IFS=","
for v in $variable
do
   # things with "$v" ...
done

Вы также можете сохранить значения в массиве, а затем пропустить его, как указано в Как разбить строку на разделителе в Bash?:

IFS=, read -ra values <<< "$variable"
for v in "${values[@]}"
do
   # things with "$v"
done

Test

$ variable="abc,def,ghij"
$ IFS=","
$ for v in $variable
> do
> echo "var is $v"
> done
var is abc
var is def
var is ghij

Вы можете найти более широкий подход в этом решении Как выполнить итерацию через список, разделенный запятыми, и выполнить команду для каждой записи.

Примеры второго подхода:

$ IFS=, read -ra vals <<< "abc,def,ghij"
$ printf "%s\n" "${vals[@]}"
abc
def
ghij
$ for v in "${vals[@]}"; do echo "$v --"; done
abc --
def --
ghij --

Ответ 4

#/bin/bash   
TESTSTR="abc,def,ghij"

for i in $(echo $TESTSTR | tr ',' '\n')
do
echo $i
done

Я предпочитаю использовать tr вместо sed, потому что sed sed имеет проблемы со специальными символами, такими как \r\n в некоторых случаях.

другим решением является установка IFS для определенного разделителя

Ответ 5

Попробуйте это.

#/bin/bash   
testpid="abc,def,ghij" 
count=`echo $testpid | grep -o ',' | wc -l` # this is not a good way
count=`expr $count + 1` 
while [ $count -gt 0 ]  ; do
     echo $testpid | cut -d ',' -f $i
     count=`expr $count - 1 `
done

Ответ 6

Другое решение, не использующее IFS и сохраняющее пробелы:

$ var="a bc,def,ghij"
$ while read line; do echo line="$line"; done < <(echo "$var" | tr ',' '\n')
line=a bc
line=def
line=ghij

Ответ 7

Вот альтернативное решение на основе tr, которое не использует эхо, выраженное в виде одной строки.

for v in $(tr ',' '\n' <<< "$var") ; do something_with "$v" ; done

Чувствуется себя лучше без эха, но это мое личное предпочтение.