리눅스 bash 스크립트에서 텍스트 파일을 읽어서 한 줄씩 배열(array) 원소로 할당하기 리눅스 bash script

리눅스 bash 스크립트에서 텍스트 파일을 읽어서 각 행을 배열(array)에 할당하는 방법이다. 예를 들어 test.txt 파일의 내용이 아래와 같다고 생각해 보자.

# test.txt 파일 내용 확인
cat test.txt
my name is john
your name is jane
his name is thomas

위의 내용을 배열 arr에 할당하는 작업이다. arr[0]의 내용은 "my name is john", arr[1]의 내용은 "your name is jame" 이런 식이 될 것이다. 배열에 대한 자세한 내용은 이전 게시물을 참고하자. 여기로

cat 명령을 이용해서 파일 내용을 출력하고 이것을 그대로 배열 변수에 할당할 경우, 한 줄씩 할당되는 것이 아니라 한 단어씩 할당된다. 아래의 예시를 보자.

# test.txt의 내용을 배열 arr에 할당
arr=(`cat test.txt`)

# 배열 원소 확인
echo ${arr[0]}
my
echo ${arr[1]}
name
echo ${arr[2]}
is

이렇게 되는 이유는 bash의 내부 필드 구분자(internal field separator)가 공백/탭/줄바꿈이기 때문이다. 따라서 한줄을 배열 원소 하나에 대응시키려면 구분자를 줄바꿈(newline) 하나로 제한시켜야 한다. 구분자는 변수 IFS에 설정되어 있다.

기존의 IFS 값을 IFS_backup 변수에 저장한 후, 배열 할당 작업을 하고 나서 원상복구하는 방식으로 작업을 하면 된다.

# 기존 IFS 백업
IFS_backup="$IFS"

# IFS 값을 줄바꿈으로 변경
IFS=$'\n'

# 배열 할당
arr=(`cat test.txt`)

# IFS 원상복구
IFS="$IFS_backup"

이제 배열 원소의 내용을 확인해 보면 하나의 원소에 파일 내용이 한 줄씩 들어가 있는 것을 볼 수 있다.

# 배열 원소 확인
echo ${arr[0]}
my name is john
echo ${arr[1]}
your name is jane

위의 예시에서 IFS 변수의 내용을 줄바꿈으로 설정할 때 echo 명령을 이용하면 제대로 되지 않음에 유의하자.

# IFS를 줄바꿈으로 설정 시도. 이런 식으로는 작동하지 않음
IFS=`echo -e "\n"`

제대로 작동하지 않는 이유는, 역따옴표(`) 안에 제시한 명령을 실행한 결과를 IFS에 할당하면서 맨 뒤에 있는 줄바꿈을 자동으로 제거하기 때문이다. 따라서 반드시 $'\n' 형태를 사용해야 한다.

# IFS를 줄바꿈으로 설정
IFS=$'\n'



핑백

덧글

  • 더나인 2019/07/10 10:50 # 삭제 답글

    안녕하세요~ 블로그 보면서 많은 도움을 얻었습니다.
    몇일동안 고민을 해봐도 잘 해결이 되지 않는 부분이 있어서 그런데 혹 도움을 얻을수 있을까요?

    아래처럼 2개의 텍스트 파일이 있는데 텍스트1 파일의 특정 부분에 텍스트2 파일의 각행의 문자열로 대치하고 싶습니다.



    # 텍스트1 파일 내용 확인
    가나다라 12.345 67.890 <---- 숫자 부분을 텍스트2 파일의 1,2필드에서 가져오고 싶습니다.
    마바사아 a bc <------ 알바펫 부분을 텍스트2 파일의 3,4필드에서 가져오고 싶습니다.

    # 텍스트2 파일 내용 확인
    42.546 74.345 d ef

    위와 같은 상황입니다.

  • 반달가면 2019/07/10 21:36 #

    제가 정확히 이해했는지 모르겠는데, 텍스트1 파일과 텍스트2 파일이 같은 수의 행을 가지고 있어서 1:1로 대체하되, 텍스트1 파일의 내용이 수자이냐 알파벳이냐에 따라 텍스트2에서 가져올 항목이 달라지는 것으로 보이네요.

    우선 텍스트1 파일에 텍스트2 파일의 내용을 다 합친 test3 파일을 새로 만든 후, test3 파일을 한 행씩 읽어서 처리하면 되지 않을까 싶습니다. 2개 파일의 내용을 하나로 모으는 방법은 이전 게시물을 참고하시기 바랍니다. awk를 이용한 방법입니다.

    [bash: awk] 2개의 파일에 있는 자료 종합하기
    http://bahndal.egloos.com/598483
  • 더나인 2019/07/10 10:54 # 삭제 답글

    한가지 빠뜨렸는데 텍스트 2 파일 행이 굉장히 많습니다.
    그걸 모두 텍스트 1 형식에 대입하고 싶습니다.

    # 텍스트2 파일 내용 확인
    42.546 74.345 d ef
    65.456 36.346 g dy
    32.346 72.673 h os
    94.366 34.389 b.cx
    .
    .
    .
  • 더나인 2019/07/11 11:08 # 삭제 답글

    답변 주셔서 너무 감사드립니다~!!
    제가 질문을 어렵게해서 원하던 답변은 아니었지만 조금더 고민을 해봐야 할것 같네요 ^^

    예시를 한글,알파벳으로 구분을 해놓기 보다 원하는곳을 구분하기 위해 숫자,알파벳으로 질문을 드렸네요.

    텍스트1 내용의 바꾸고 싶은 부분에 텍스트2의 각행의 특정 부분을 대치하는 개념입니다.


    결과물-------------
    사자하타
    가나다라 [텍스트2 파일 1행의 1,2필드 대치]
    마바사아 [텍스트2 파일 1행의 3,4필드 대치]
    하나호다

    사자하타
    가나다라 [텍스트2 파일 2행의 1,2필드 대치]
    마바사아 [텍스트2 파일 2행의 3,4필드 대치]
    하나호다

    사자하타
    가나다라 [텍스트2 파일 3행의 1,2필드 대치]
    마바사아 [텍스트2 파일 3행의 3,4필드 대치]
    하나호다

    이런식으로 텍스트2 파일의 행 갯수 만큼 위 형식으로 결과물이 나와야합니다.
    다시한번 답변 주셔서 감사드립니다.
    많이 더 고민해볼게요 ^^

  • 반달가면 2019/07/12 09:42 #

    결과물 쓰신 것처럼 계속 반복되는 패턴에 텍스트2의 내용을 가져다가 같이 표시하는 상황이면 아래와 같은 예시도 참고해 보시기 바랍니다. 필드 구분은 탭(t)으로 하였습니다.

    awk '{ print "사자하타n가나다라t" $1 "t" $2 "n마바사아t" $3 "t" $4 "n하나호다n" }' test2.txt
  • 우야 2019/07/25 17:24 # 삭제 답글

    답변 감사드립니다 !!
    말씀해주신대에서 응용하면 원하는 답을 얻을수 있을것 같습니다.
    밑도 끝도 없이 답만 원하는 댓글에 친절히 답변 주셔서 감사합니다~
    항상 좋은 일들만 가득하길 바랄게요~!!
  • 반달가면 2019/07/25 21:06 #

    도움 되었다니 다행입니다~
  • 하하호호 2019/09/18 16:02 # 삭제 답글

    # test.txt의 내용을 배열 arr에 할당
    arr=(`cat test.txt`)

    이렇게 하니 그냥 안에 있는 문자가 그대로 할당이 되는데 파일의 내용을 배열에 할당하려면 어떻게 하나요?
  • 반달가면 2019/09/18 21:13 #

    본문의 예시대로 하면 test.txt 파일의 내용이 할당되어야 정상입니다. 혹시 따옴표를 잘못 사용한 것은 아닌지 확인해 보시기 바랍니다. 작은 따옴표(')가 아니라 역따옴표(`)를 사용하셔야 합니다.
  • 두얼굴의 허스키 2019/09/18 21:52 #

    아하 작은 따옴표가 아니라 tilde키 였군요. 감사합니다. 본문과 같이 출력이 잘되네요.
  • 2019/09/20 08:13 # 답글 비공개

    비공개 덧글입니다.
  • 2019/09/20 14:55 # 비공개

    비공개 답글입니다.
  • 2019/09/21 14:42 # 비공개

    비공개 답글입니다.
  • 2019/09/21 15:24 # 비공개

    비공개 답글입니다.
  • 2019/09/22 12:00 # 비공개

    비공개 답글입니다.
  • 2019/09/23 07:04 # 비공개

    비공개 답글입니다.
  • 2019/09/23 10:14 # 비공개

    비공개 답글입니다.
  • 두얼굴의 허스키 2019/09/23 10:16 # 답글

    네 문자를 다른 것으로 바꾸는 것은 상관이 없을 것 같습니다.
  • 반달가면 2019/09/23 21:18 #

    문의하신 사항에 대하여, 아래의 링크를 참고해 보시기 바랍니다. 별도의 게시물로 올렸습니다.

    http://bahndal.egloos.com/631090
댓글 입력 영역
* 비로그인 덧글의 IP 전체보기를 설정한 이글루입니다.

Google Analytics


B-Side


adsense(w160_h600)2

통계 위젯 (화이트)

68342
4132
1862259

ad_widget_2