[bash] 변수에 값을 할당하여 파일을 한 줄씩 읽습니다.

다음 .txt 파일이 있습니다.

Marco
Paolo
Antonio

한 줄씩 읽고 싶습니다. 각 줄마다 .txt 줄 값을 변수에 할당하고 싶습니다. 내 변수가이라고 가정하면 $name흐름은 다음과 같습니다.

  • 파일에서 첫 번째 줄 읽기
  • 할당 $name= “마르코”
  • 몇 가지 작업을 수행 $name
  • 파일에서 두 번째 줄 읽기
  • Assign $name= “Paolo”


답변

다음은 한 줄씩 인수로 전달 된 파일을 읽습니다.

while IFS= read -r line; do
    echo "Text read from file: $line"
done < my_filename.txt

이것은 루프에서 파일에서 행을 읽는 표준 형식 입니다. 설명:

  • IFS=(또는 IFS='') 선행 / 후행 공백이 잘리지 않도록합니다.
  • -r 백 슬래시 이스케이프가 해석되지 않도록합니다.

또는 bash 파일 도우미 스크립트 (예제 내용)에 넣을 수 있습니다.

#!/bin/bash
while IFS= read -r line; do
    echo "Text read from file: $line"
done < "$1"

위의 파일 이름이 filename으로 스크립트에 저장 readfile되면 다음과 같이 실행할 수 있습니다.

chmod +x readfile
./readfile filename.txt

파일이 표준 POSIX 텍스트 파일이 아닌 경우 (= 개행 문자로 끝나지 않음) 후행 부분 행을 처리하도록 루프를 수정할 수 있습니다.

while IFS= read -r line || [[ -n "$line" ]]; do
    echo "Text read from file: $line"
done < "$1"

여기 || [[ -n $line ]]에서 마지막 줄이 E로 끝나지 않으면 0이 아닌 종료 코드를 반환 \n하므로 끝으로 무시되지 않도록 read합니다.

루프 내부의 명령이 표준 입력에서도 읽히는 경우에 사용되는 파일 디스크립터 read는 다른 표준 파일 디스크립터를 피할 수 있습니다 . 예를 들면 다음과 같습니다.

while IFS= read -r -u3 line; do
    echo "Text read from file: $line"
done 3< "$1"

비 Bash 쉘은 알지 못할 수도 read -u3있으므로 read <&3대신 사용하십시오.


답변

다음을 나타내는 -r플래그 를 사용하는 것이 좋습니다 read.

-r  Do not treat a backslash character in any special way. Consider each
    backslash to be part of the input line.

에서 인용하고 man 1 read있습니다.

또 다른 것은 파일 이름을 인수로 취하는 것입니다.

업데이트 된 코드는 다음과 같습니다.

#!/usr/bin/bash
filename="$1"
while read -r line; do
    name="$line"
    echo "Name read from file - $name"
done < "$filename"


답변

다음 Bash 템플릿을 사용하면 파일에서 한 번에 하나의 값을 읽고 처리 할 수 ​​있습니다.

while read name; do
    # Do what you want to $name
done < filename


답변

#! /bin/bash
cat filename | while read LINE; do
    echo $LINE
done


답변

많은 사람들이 과도하게 최적화 된 솔루션을 게시했습니다. 나는 그것이 틀렸다고 생각하지 않지만 겸손하게 모든 사람들 이이 작동 방식을 쉽게 이해할 수 있도록 덜 최적화 된 솔루션이 바람직하다고 생각합니다. 내 제안은 다음과 같습니다.

#!/bin/bash
#
# This program reads lines from a file.
#

end_of_file=0
while [[ $end_of_file == 0 ]]; do
  read -r line
  # the last exit status is the 
  # flag of the end of file
  end_of_file=$?
  echo $line
done < "$1"


답변

사용하다:

filename=$1
IFS=$'\n'
for next in `cat $filename`; do
    echo "$next read from $filename"
done
exit 0

IFS다르게 설정 하면 이상한 결과가 나타납니다.


답변

입력 파일과 사용자 입력 (또는 stdin의 다른 것)을 모두 처리해야하는 경우 다음 해결 방법을 사용하십시오.

#!/bin/bash
exec 3<"$1"
while IFS='' read -r -u 3 line || [[ -n "$line" ]]; do
    read -p "> $line (Press Enter to continue)"
done

허용 된 답변bash-hackers 리디렉션 자습서를 기반으로 합니다 .

여기서 스크립트 인수로 전달 된 파일에 대해 파일 설명자 3을 열고이 read설명자를 입력 ( -u 3) 으로 사용하도록 지시합니다 . 따라서 기본 입력 설명자 (0)를 터미널이나 다른 입력 소스에 연결하여 사용자 입력을 읽을 수 있습니다.