HOWTO · Linux

Bash를 사용하여 한 줄씩 파일을 읽는 방법

Bash에서 읽기 명령을 사용하여 한 줄씩 파일을 읽습니다.

이 페이지의 내용

Bash에서는 while 루프 안에서 read 명령을 사용해 텍스트 파일을 한 줄씩 처리할 수 있습니다. 입력을 스트림으로 읽으므로 스크립트가 파일 전체를 메모리에 저장할 필요가 없습니다. 앞뒤 공백을 유지하려면 IFS=를 사용하고, 백슬래시를 그대로 보존하려면 -r을 사용하세요. 값을 확장할 때는 항상 "$line"처럼 따옴표로 감싸세요.

while 루프로 파일을 한 줄씩 읽기

안정적인 루프는 입력 리디렉션으로 파일을 읽습니다. || [[ -n $line ]] 조건을 함께 사용하면 파일 끝에 줄바꿈 문자가 없어도 마지막 줄을 처리할 수 있습니다. 루프는 파일을 스트림으로 읽고, 누적 합계는 현재 셸에 유지합니다.

아래의 완전한 예제는 숫자 입력 파일을 직접 만들고 각 값을 출력한 뒤, 여섯 숫자 1, 5, 6, 7, 8, 10을 모두 더합니다. 합계는 37입니다. 코드와 출력에 표시되는 레이블 및 문장은 영어로 남아 있으며, 각 숫자를 보여 준 다음 합계를 표시한다는 뜻입니다.

#!/usr/bin/env bash
set -u

file=$(mktemp)
trap 'rm -f "$file"' EXIT
printf '%s\n' 1 5 6 7 8 10 > "$file"
sum=0
printf 'The numbers in the file are:\n'
while IFS= read -r line || [[ -n $line ]]; do
  printf '%s\n' "$line"
  sum=$((sum + line))
done < "$file"
printf 'The sum of the numbers in the file is:%s\n' "$sum"
The numbers in the file are:
1
5
6
7
8
10
The sum of the numbers in the file is:37

입력 리디렉션을 사용하면 루프가 현재 셸에서 실행되므로 누적 합계 같은 변경 사항을 루프가 끝난 뒤에도 사용할 수 있습니다. $line처럼 따옴표로 감싸지 않은 확장은 피하세요. 단어 분리와 경로명 확장으로 값이 달라질 수 있습니다.

각 줄을 필드로 나누기

구분자를 기준으로 레코드를 나누려면 먼저 원본 줄을 읽은 다음 필드를 변수에 할당하세요. 구분자를 사용하는 read에서 마지막 변수는 남은 필드를 받습니다. 이 예제는 Rohit-10, Harish-30, Manish-50, Kapil-10, Anish-20의 다섯 레코드를 모두 만들고 처리합니다. 마지막 줄 보호 조건을 사용하면 파일 끝에 줄바꿈 문자가 없어도 비어 있지 않은 마지막 레코드를 처리합니다.

#!/usr/bin/env bash
set -u

file=$(mktemp)
trap 'rm -f "$file"' EXIT
printf '%s\n' 'Rohit-10' 'Harish-30' 'Manish-50' 'Kapil-10' 'Anish-20' > "$file"
while IFS= read -r line || [[ -n $line ]]; do
  IFS=- read -r name earnings <<< "$line"
  printf '%s has made earnings of %s pounds today!\n' "$name" "$earnings"
done < "$file"
Rohit has made earnings of 10 pounds today!
Harish has made earnings of 30 pounds today!
Manish has made earnings of 50 pounds today!
Kapil has made earnings of 10 pounds today!
Anish has made earnings of 20 pounds today!

여기서 IFS=-는 필드 할당을 위한 read에서 하이픈을 구분자로 지정합니다. 변수가 두 개라면 name은 첫 번째 하이픈 앞의 텍스트를 받고, earnings는 나머지 텍스트를 받습니다. 출력할 때 변수 값을 각각 하나의 값으로 전달하도록 따옴표로 감싸세요.

다른 Bash 파일 읽기 방법 선택하기

각 줄이 들어오는 대로 처리하거나 파일이 사용 가능한 메모리보다 클 수 있다면 while IFS= read -r line 패턴을 사용하세요. 일반 파일은 루프에 직접 리디렉션하면 됩니다. cat을 프로세스 치환으로 실행해도 이 경우에는 이점이 없습니다. 파일 대신 명령에서 생성된 출력을 루프가 읽어야 한다면 프로세스 치환이 유용할 수 있습니다.

설치된 Bash에서 mapfile을 제공한다면 mapfile -t lines < "$file"처럼 파일의 줄을 배열에 불러올 수 있습니다. 이후 단계에서 줄을 인덱스로 접근하거나 여러 번 순회해야 하고 파일 전체가 메모리에 들어갈 때 이 방법을 선택하세요. -t 옵션은 각 줄 끝의 줄바꿈 문자를 제거합니다. mapfile의 사용 가능 여부는 Bash 설치 환경에 따라 다르므로, 더 폭넓게 적용되는 방법이 필요하면 스트리밍 루프를 사용하세요.