쉘 스크립트의 단일 for 루프에서 여러 변수를 어떻게 사용할 수 있습니까?

쉘 스크립트의 단일 for 루프에서 여러 변수를 어떻게 사용할 수 있습니까?

for 루프를 사용하여 다음 코드를 구현했지만 스크립트를 실행한 후 오류가 출력됩니다.

for i in `awk -F"|" '{print $1}' $INPUTFILE`, j in `awk -F"|" '{print $2}' $INPUTFILE`
do
echo $i:$j
done  

쉘 스크립트의 단일 for 루프에서 여러 변수를 사용하도록 도와주세요.

답변1

bash는 여러 변수가 있는 루프를 허용하지만 C와 유사한 구문만 사용합니다.

for ((i=0,j=10;i<=j;i++,j--))
do
   echo "i=$i"
   echo "j=$j"
done

답변2

아마도 당신은 실제로 다음을 원할 것입니다.

while IFS='|' read -r i j rest <&3; do
  {
    printf '%s\n' "something with $i and $j"
  } 3<&-
done 3< "$INPUTFILE"

하지만쉘 루프를 사용하여 텍스트를 처리하는 것은 일반적으로 잘못된 접근 방식입니다..

여기에는 다음이 필요한 것 같습니다.

awk -F '|' '{print $1 ":" $2}' < "$INPUTFILE"

이제 제목의 질문에 대한 답변으로 for여러 변수가 있는 루프가 있는 셸의 경우 다음을 얻을 수 있습니다 zsh(명령 대체를 분할할 때 변수를 인용하지 않거나 와일드카드를 비활성화하지 않고 이미 zsh 구문을 사용하고 있는 것 같습니다).

$ for i j in {1..6}; do echo $i:$j; done
1:2
3:4
5:6

또는 더 짧은 형식:

for i j ({1..6}) echo $i:$j

POSIX 쉘과 동일:

set -- 1 2 3 4 5 6
## or:
# IFS='
# ' # split on newline
# set -o noglob # disable globbing
# set -- $(awk ...) # split the output of awk or other command
while [ "$#" -gt 0 ]; do
  printf '%s\n' "$1:$2"
  shift 2
done

답변3

파일의 출력을 변수에 저장한 다음 두 부분으로 나눌 수 있습니다. 예:

존재하다파일 내용은 다음과 같습니다.

a:1
b:2
c:3
d:4

이제 스크립트입니다.

#!/bin/bash
for n in $(cat example)
do
    first=$(echo $n | cut -d ":" -f 1)
    second=$(echo $n | cut -d ":" -f 2)
    echo $first
    echo $second
done

답변4

임베디드 시스템에서는 사용 가능한 항목 때문에 어려움을 겪는 경우가 많습니다. 예를 들어. for변수는 하나만 있을 수 있습니다. awk&는 printf전혀 사용할 수 없거나 IFS지원되지 않습니다.

이러한 경우 다음과 같이 목표를 달성할 수 있습니다.

export i=xxx
for j in `cat INPUTFILE` ; do \
    [ $i == xxx ] && export i=$j && continue ; \
    echo "$i:$j" ; \
    export i=xxx ; \
done
unset i

보다 일반적인 형태의 솔루션은 다음과 같습니다.

export A=xxx
export B=xxx
for i in 1 2 3 4 5 6 7 8 9 10 11 ; do \
    [ $A == xxx ] && export A=$i && continue ; \
    [ $B == xxx ] && export B=$i && continue ; \
    echo "$A:$B:$i" ; \
    export A=xxx ; \
    export B=xxx ; \
done
unset A
unset B
  • 문자열 "xxx"가 데이터세트에 전혀 나타나지 않는다고 가정해 보겠습니다. 만약 그것이 나타날 수 있다면 다른 것을 선택하세요.
  • 각 "레코드"에는 "필드"가 얼마든지 있을 수 있습니다. {A,B,...} 필드를 처리하는 4개의 행을 각각 복사하면 됩니다.
  • 마지막 필드는 항상 $i...라고 합니다 . 도움이 된다면 export C=$i앞에 필드를 추가해도 됩니다.echo
  • 데이터 세트의 문자열 수가 레코드 크기의 배수가 아닌 경우 "나머지"(예: |set| % |record|)는 손실됩니다.

관련 정보