읽기 루프 동안 읽기 명령을 사용할 때 문제가 발생합니다.

읽기 루프 동안 읽기 명령을 사용할 때 문제가 발생합니다.

입력 텍스트 파일을 한 줄씩 읽고 두 문자열을 텍스트 파일의 각 줄에 대한 변수로 전달하기 위해 while read 루프 줄을 설정하려고 합니다.

    while IFS= read -r line
do
    # Read and pass two path strings as variables.
    read path1 path2
    echo "$path1"
    echo "$path2"
done < "$1"

read path1 path2현재 줄의 각 문자열에 변수를 할당하기 전에 텍스트 파일의 다음 줄을 처리하는 것 같습니다.

다음 줄로 이동하기 전에 각 줄에 문자열을 변수로 어떻게 전달할 수 있나요?

답변1

read루프 본문 내부의 두 번째 항목은 여기서 올바르지 않습니다. readwhile 루프의 일부로 실제로 첫 번째 호출보다 한 줄 앞서 있습니다. 따라서 귀하의 요구 사항에 따라 이러한 변수를 첫 번째 변수의 일부로 읽으십시오.read

while read -r path1 path2; do
    echo "$path1"
    echo "$path2"
done < "$1"

여기에서 볼 수 있듯이 IFS=필드 구분 기호를 재설정하면 전체 행만 선택되므로 두 변수를 모두 읽을 때 설정도 올바르지 않습니다. 두 개의 변수를 읽으면 기본값(공백, 탭, 줄바꿈과 같은 공백 문자)을 사용하여 공백으로 구분된 목록에 각 행의 값이 저장됩니다. 이 방법으로 행을 구분하는 n개의 열을 가질 수 있고 n개의 변수를 사용하여 읽을 수 있습니다.

이제 이러한 변수에서 값을 사용할 수 있으며 필요에 따라 다른 명령에 전달할 수 있습니다.

샘플 입력 파일에서 이것이 어떻게 작동하는지 살펴보겠습니다.

foo bar
foo1 bar1
foo2 bar2

-xset을 사용하여 디버그 모드에서 첫 번째 스크립트를 실행합니다.

$ bash -x script.sh
+ read -r path1 path2
+ echo 1
1
+ echo 2
2
+ read -r path1 path2
+ echo 3
3
+ echo 4
4
+ read -r path1 path2
+ echo abc
abc
+ echo def
def
+ read -r path1 path2

답변2

라인을 그대로 유지하고 싶다면그리고그것에서 값을 추출하려면 다음을 사용할 수 있습니다.여기에 있는 문자열:

while IFS= read -r line; do
    read -r path1 path1 <<< "$line"
    echo "$line"
    echo "$path1:$path2"
done < file

실제로 모든 쉘이 here-string을 지원하는 것은 아닙니다. 그러나 이 문서는 모든 POSIX 유형 셸에서 지원됩니다.

while IFS= read -r line; do
    read -r path1 path1 << _LINE_
$line
_LINE_
    echo "$line"
    echo "$path1:$path2"
done < file

답변3

파일을 for루프로 리디렉션하면 루프 전체에서 표준 입력의 모든 읽기가 동일한 파일에서 읽혀집니다. 즉, read루프의 두 명령은 첫 번째 인수로 스크립트에 전달한 파일에서 대체 줄을 읽습니다.

path1데이터를 어디서 가져오길 원하는지 조금 불분명합니다 path2. 파일에서 이를 읽으려면 루프 헤더에서 수행하십시오.

while read -r path1 path2; do
    printf 'path1 = "%s"\n' "$path1"
    printf 'path2 = "%s"\n' "$path2"
done <"somefile"

이 답변의 나머지 부분에서는 파일에서 무언가를 읽은 다음 루프의 터미널에서 무언가를 읽으려고 한다고 가정합니다.

read루프 본문을 터미널에서 읽도록 하려면 :

exec 3<"somefile"

while IFS= read -r words <&3; do
   read -r word1 word2 junk
   printf 'Got words = "%s"\n' "$words"
   printf 'Got word1 = "%s"\n' "$word1"
   printf 'Got word2 = "%s"\n' "$word2"
done

이렇게 하면 첫 번째 입력은 readfile 에서 나오고 somefile, 두 번째 표준 입력 스트림은 read터미널(또는 스크립트의 표준 입력 스트림이 나오는 곳)에서 읽혀집니다.

관련 정보