중첩 된 while 루프에서 한 번에 한 줄씩 두 개의 입력 파일에서 읽는 방법이 있는지 알고 싶었습니다. 예를 들어, 두 개의 파일 FileA
과 FileB
.
FileA :
[jaypal:~/Temp] cat filea
this is File A line1
this is File A line2
this is File A line3
FileB :
[jaypal:~/Temp] cat fileb
this is File B line1
this is File B line2
this is File B line3
현재 샘플 스크립트 :
[jaypal:~/Temp] cat read.sh
#!/bin/bash
while read lineA
do echo $lineA
while read lineB
do echo $lineB
done < fileb
done < filea
실행:
[jaypal:~/Temp] ./read.sh
this is File A line1
this is File B line1
this is File B line2
this is File B line3
this is File A line2
this is File B line1
this is File B line2
this is File B line3
this is File A line3
this is File B line1
this is File B line2
this is File B line3
이것은 FileA의 각 줄에 대해 FileB를 완전히 반복합니다. 계속, 중단, 종료를 사용해 보았지만 원하는 결과를 얻을 수있는 것은 없습니다. 스크립트가 파일 A에서 한 줄만 읽은 다음 FileB에서 한 줄을 읽고 루프를 종료하고 파일 A의 두 번째 줄과 파일 B의 두 번째 줄을 계속 읽으려고합니다. 다음 스크립트와 유사한 것-
[jaypal:~/Temp] cat read1.sh
#!/bin/bash
count=1
while read lineA
do echo $lineA
lineB=`sed -n "$count"p fileb`
echo $lineB
count=`expr $count + 1`
done < filea
[jaypal:~/Temp] ./read1.sh
this is File A line1
this is File B line1
this is File A line2
this is File B line2
this is File A line3
this is File B line3
while 루프로 이것이 가능합니까?
첫 번째 파일에서 일부 문자가 발생하지 않는다는 것을 확실히 알고 있다면 붙여 넣기를 사용할 수 있습니다.
기본 구분 기호 탭을 사용한 붙여 넣기의 예 :
paste file1 file2 | while IFS="$(printf '\t')" read -r f1 f2
do
printf 'f1: %s\n' "$f1"
printf 'f2: %s\n' "$f2"
done
다음을 사용한 붙여 넣기의 예 @
:
paste -d@ file1 file2 | while IFS="@" read -r f1 f2
do
printf 'f1: %s\n' "$f1"
printf 'f2: %s\n' "$f2"
done
문자가 첫 번째 파일에서 발생하지 않는 것이 보장되면 충분합니다. 이것은 마지막 변수를 채울 때 read
무시 하기 때문 입니다 IFS
. 따라서 @
두 번째 파일에서 발생 하더라도 분할되지 않습니다.
확실한 코드를 위해 몇 가지 bash 기능을 사용한 붙여 넣기의 예 :
while IFS=$'\t' read -r f1 f2
do
printf 'f1: %s\n' "$f1"
printf 'f2: %s\n' "$f2"
done < <(paste file1 file2)
사용 된 Bash 기능 : ansi c 문자열 ( $'\t'
) 및 프로세스 대체 ( <(...)
)를 사용 하여 서브 쉘 문제에서 while 루프 를 방지합니다 .
두 파일 모두에서 어떤 문자도 발생하지 않을지 확신 할 수없는 경우 파일 설명자를 사용할 수 있습니다 .
while true
do
read -r f1 <&3 || break
read -r f2 <&4 || break
printf 'f1: %s\n' "$f1"
printf 'f2: %s\n' "$f2"
done 3<file1 4<file2
많이 테스트되지 않았습니다. 빈 줄에서 끊어 질 수 있습니다.
파일 설명자 번호 0, 1 및 2는 이미 각각 stdin, stdout 및 stderr에 사용됩니다. 3 이상의 파일 설명자는 (일반적으로) 무료입니다. bash 매뉴얼은 "내부적으로 사용"되기 때문에 9보다 큰 파일 설명자를 사용하지 않도록 경고합니다.
열린 파일 설명자는 쉘 함수 및 외부 프로그램에 상속됩니다. 열린 파일 설명자를 상속하는 함수 및 프로그램은 파일 설명자를 읽고 쓸 수 있습니다. 함수 또는 외부 프로그램을 호출하기 전에 필요하지 않은 모든 파일 설명자를 닫도록주의해야합니다.
다음은 실제 작업 (인쇄)과 메타 작업 (두 파일을 병렬로 한 줄씩 읽음)과 분리 된 위와 동일한 프로그램입니다.
work() {
printf 'f1: %s\n' "$1"
printf 'f2: %s\n' "$2"
}
while true
do
read -r f1 <&3 || break
read -r f2 <&4 || break
work "$f1" "$f2"
done 3<file1 4<file2
이제 우리는 작업 코드를 제어 할 수없는 척하고 그 코드는 어떤 이유로 든 파일 설명자 3에서 읽으려고합니다.
unknowncode() {
printf 'f1: %s\n' "$1"
printf 'f2: %s\n' "$2"
read -r yoink <&3 && printf 'yoink: %s\n' "$yoink"
}
while true
do
read -r f1 <&3 || break
read -r f2 <&4 || break
unknowncode "$f1" "$f2"
done 3<file1 4<file2
다음은 예제 출력입니다. 첫 번째 파일의 두 번째 줄은 루프에서 "도난"된 것입니다.
f1: file1 line1
f2: file2 line1
yoink: file1 line2
f1: file1 line3
f2: file2 line2
다음은 외부 코드 (또는 해당 문제에 대한 코드)를 호출하기 전에 파일 설명자를 닫는 방법입니다.
while true
do
read -r f1 <&3 || break
read -r f2 <&4 || break
# this will close fd3 and fd4 before executing anycode
anycode "$f1" "$f2" 3<&- 4<&-
# note that fd3 and fd4 are still open in the loop
done 3<file1 4<file2
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다