[shell] 쉼표로 구분 된 쉘 변수를 통해 루프

아래와 같이 Unix 쉘 변수가 있다고 가정합니다.

variable=abc,def,ghij

for 루프를 사용하여 모든 값 ( abc, defghij) 을 추출하고 각 값을 프로 시저에 전달 하고 싶습니다 .

스크립트는에서 쉼표로 구분 된 값의 임의 개수를 추출 할 수 있어야합니다 $variable.



답변

다음 스크립트를 사용하여 쉼표로만 구분되는 한 필드 수에 관계없이 변수를 동적으로 탐색 할 수 있습니다.

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"위 의 호출 대신 for 루프 내부 dodone내부에서 프로 시저를 호출 할 수 있습니다 proc "$i".


업데이트 : 변수 값에 공백이 없으면 위의 스 니펫이 작동합니다. 이러한 요구 사항이있는 경우 변경할 수있는 솔루션 중 하나를 사용한 IFS다음 변수를 구문 분석하십시오.


도움이 되었기를 바랍니다.


답변

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


답변

다른 필드 구분자를 설정하면 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

테스트

$ 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 --


답변

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

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

sed 대신 tr을 사용하는 것을 선호합니다. sed는 경우에 따라 \ r \ n과 같은 특수 문자에 문제가 있기 때문입니다.

다른 해결책은 IFS를 특정 구분자로 설정하는 것입니다.


답변

다음은 에코를 사용하지 않는 대체 tr 기반 솔루션으로, 한 줄로 표현됩니다.

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

메아리없이 깔끔하게 느껴지지만 개인적 취향 일뿐입니다.


답변

이거 한번 해봐.

#/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


답변

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