FOR 루프: 파일에서 동시에 2개의 변수 전달

FOR 루프: 파일에서 동시에 2개의 변수 전달

파일에서 2개의 변수를 추출하는 쉘 스크립트를 작성 중이며 아래 FOR 루프를 사용했습니다.

for i j in `cat list`
                do
                echo title
                echo total "$i" "," "$j"
                echo end
done

고양이 목록 어딨어

AAA 111
BBB 222
CCC 333

예상치 못한 'j' 오류가 발생했습니다. 'while 루프'를 사용했지만 운이 없었습니다.

예상 출력은 다음과 같습니다.

title
total AAA,111
total BBB,222
total CCC,333
end

답변1

for실제로 또는 루프가 필요하지 않습니다 . while다음 명령 중 하나가 awk작동합니다.

awk 'BEGIN {print "title"}
           {print "total",$1","$2}
       END {print "end"}' list

또는:

awk 'BEGIN {print "title"}
           {printf "total %s,%s\n", $1, $2}
       END {print "end"}' list

파일의 데이터를 읽기 전에 BEGIN{print "title"}단어를 한 번 인쇄하십시오.title

{print "total",$1","$2}total열 값 사이의 공백을 나타내는 따옴표가 없는 쉼표 뒤에 단어를 인쇄한 다음 열 자체를 인쇄합니다. 이 블록은 각 입력 행에 대해 실행됩니다.

END{print "end"}end파일의 단어와 끝을 인쇄합니다 . END는 파일에서 최종 입력을 읽은 후 블록을 실행하도록 지시합니다.

두 번째 명령의 경우:

유일한 차이점은 다음과 같습니다.

{printf "total %s,%s\n", $1, $2}

이는 형식이 정의된 위치 printf대신 print첫 번째 매개변수를 사용합니다.

%s,%s및 의 값을 쉼표로 구분하여 인쇄하고, $1다음 줄로 이동하려면 새 줄을 나타내어 파일 끝까지 및 의 값을 인쇄하도록 지시합니다.$2\n$1$2

개인적으로 저는 따옴표 와 쉼표를 printf모두 사용하는 대신 하나의 따옴표 세트만 사용할 수 있기 때문에 두 번째 명령을 사용하겠습니다 . total또한 매뉴얼 페이지를 읽어보면 알 수 있듯이 더욱 모듈화되어 있습니다. 두 가지 다른 방법을 보여주기 위해 두 가지 명령만 포함했습니다.

산출

title
total AAA,111
total BBB,222
total CCC,333
end

답변2

당신은 그것을 사용할 수 있습니다 while read:

echo "title"
while read -r i j
do
    echo total "$i,$j"
done < list
echo "end"

출력은 다음과 같습니다.

title
total AAA,111
total BBB,222
total CCC,333
end

답변3

특정 문제는 텍스트 처리 유틸리티를 사용하면 더 잘 해결될 수 있지만awk@Nasir가 보여준 것처럼(당신은 또한 볼 수 있습니다쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?) 제목의 질문에 답해 드리겠습니다.

구문은 for i j in words...; do something with $i and $j; done아직 zsh지원되지 않습니다 bash.

또한 bash분할(원하는 것) 및 와일드카드(원하지 않는 것) `cmd`(전환하려는 구식 명령 대체 형식 $(cmd)) 를 수행하고 zsh예상한 대로만 분할합니다.

bash다른 POSIX 유사 셸을 사용하여 한 번에 두 단어를 처리하려면 for i j in words...다음을 수행할 수 있습니다.

set -- words...
while [ "$#" -gt 0 ]; do
  i=$1 j=$2 # or j=${2-missing}
  something with "$i" and "$j"
  shift "$(( 2 - ($# == 1) ))"
done

귀하의 경우에는 set다음과 같습니다.

set -o noglob # disable globbing
set -- $(cat list)

(수정이 없다고 가정하면 $IFS기본적으로 공백, 탭 및 줄 바꿈이 포함됩니다).

관련 정보