우리가 작업을 하다 보면, 외부 텍스트 파일의 내용을 IDL로 읽어들여서 데이터로 활용해야 하는 경우도 있지만, 반대로 IDL에서 작업한결과물들을 외부 텍스트 파일로 전달하여 써야 하는 경우 즉 텍스트 파일을 내가 직접 생성해야 하는 경우도 있습니다. 오늘은 후자의 방법, 즉 텍스트 파일(또는 ASCII 파일)을 쓰는 방법에 관한 얘기를 해보고자 합니다. 참고로, 텍스트 파일을 읽는 방법에 관해서는 제가 예전에 4회에 걸쳐서 연재 게시물들을 올린 적이 있었으므로, 관심있으신 분들은 그 내용을 참조하시면 됩니다. (아래 링크 참조)
효과적인 설명을 위하여 다음과 같은 예제 데이터를 가정해보고자 합니다. 어떤 야구팀에 속한 5명의 선수들이 있고 이 선수들의 이름, 타수, 안타수 값들이 배열의 형태로 존재한다고 가정합니다. 그리고 안타수를 타수로 나누면 타율값이 계산될텐데, 타율값들에 해당되는 배열도 다음과 같이 생성이 가능합니다.
player = ['AAA', 'BBB', 'CCC', 'DDD', 'EEE']
ab = [339, 284, 372, 306, 297]
hit = [91, 88, 113, 78, 82]
bavg = FLOAT(hit)/ab
이제 이 데이터를 외부 텍스트 파일에 쓰는 작업을 시도해야 할텐데요. 그 전에 먼저 쓰여질 값들을 미리 화면상에서 출력해보는 것이 좋습니다. 그래야 실제 텍스트 파일의 내용이 어떻게 될 것인지 미리 가늠해볼 수 있기 때문입니다. 이 작업은 다음과 같이 반복형 구문의 형태로 구현하면 됩니다.
FOR j = 0, N_ELEMENTS(player)-1 DO $
PRINT, player[j], ab[j], hit[j], bavg[j]
여기까지의 내용만으로 프로그램을 실행해보면 다음과 같은 출력 결과를 얻을 수 있습니다.
AAA 339 91 0.268437
BBB 284 88 0.309859
CCC 372 113 0.303763
DDD 306 78 0.254902
EEE 297 82 0.276094
이 정도면 어느 정도 예상했던 결과이고 형식도 그리 나쁘지 않습니다. 그러면 이 내용을 그대로 담는 텍스트 파일을 생성해 보기로 합시다. 이러한 작업에 있어서는 기본적으로 OPENW, PRINTF 두 명령을 잘 알아두고 활용하면 됩니다. 전체 내용을 먼저 적어보면 다음과 같습니다.
OPENW, lunw, 'bat_stat.txt', /GET_LUN
FOR j = 0, N_ELEMENTS(player)-1 DO $
PRINTF, lunw, player[j], ab[j], hit[j], bavg[j]
FREE_LUN, lunw
여기서는 먼저 시작과 끝 부분에 있는 OPENW 및 FREE_LUN 명령을 주목해야 하는데요. OPENW는 생성하고자 하는 파일을 준비시키는 역할 정도로 보면 됩니다. OPENW라는 명령의 의미를 풀어서 언급한다면 OPEN (Write) 정도로 생각하면 됩니다. 생성할 텍스트 파일의 이름은 'bat_stat.txt'입니다. 여기서 lunw라는 변수는 IDL과 파일 사이의 교신을 위한 통로 번호 정도로 생각하면 되는데, 약간 전문적인 용어로는 LUN 또는 Logical Unit Number라고도 부릅니다. 원래는 1~99 범위 내의 정수형 값을 직접 명시해도 되지만, 여기서는 /GET_LUN 키워드를 사용함으로써 번호 자체를 IDL이 알아서 부여하도록 처리한 것입니다. IDL과 외부 파일 사이의 교신 채널 번호 정도의 의미로 생각해도 좋을 것 같습니다. 이러한 채널을 먼저 열어둔 다음, 쓸 내용을 이 채널을 통하여 전달하는 작업을 진행하고, 이 작업이 다 끝난 후에는 교신 채널을 반드시 닫아줘야 합니다. 채널을 닫아주는 역할은 FREE_LUN 명령이 담당합니다.
따라서 OPENW와 FREE_LUN 사이에서는 내가 원하는 내용들을 외부 텍스트 파일에 출력하는 작업이 필요한데, 이러한 작업에 있어서는 PRINTF 명령이 필요합니다. 그냥 PRINT 명령은 화면상에(콘솔창에) 출력하는 역할이지만, PRINTF는 화면이 아닌 외부 파일에 출력하는 역할을 담당합니다. 사실 PRINT와 PRINTF는 출력 방향의 차이 정도만 있을 뿐이고 나머지 사용 방식은 서로 거의 비슷합니다. 따라서 앞서 사용했던 PRINT문의 내용과 방금 사용된 PRINTF의 내용은 거의 유사합니다. 다만 PRINTF의 경우는 출력의 방향이 파일이므로, 교신 채널 번호 값을 담은 변수인 lunw가 반드시 필요하다는 점만 유의하면 됩니다.
여기까지 문제없이 진행되었다면 실제로 'bat_stat.txt'라는 파일이 현재 디렉토리 안에 생성되어 있을 것입니다. 이 파일의 내용을 살펴보면, 앞서 PRINT문으로 화면상에 출력했던 모습과 동일한 내용임을 확인할 수 있습니다. 여러분들도 직접 확인해보시기 바랍니다.
이 정도면 원하는 내용을 담은 텍스트 파일을 생성했다고 볼 수도 있을텐데요. 하지만 좀 더 생각해봐야 할 부분도 있습니다. 경우에 따라서는 출력에 있어서 형식(Format)을 직접 명시해줘야 할 수도 있습니다. 지금 이 경우를 본다면, 타율의 값을 0.xxx와 같이 소수점 세째 자리까지만 출력되게 할 필요도 있어 보이고, 또 컬럼간 간격도 직접 조정해주는 것이 필요해 보이기도 합니다. 이와 같이 출력될 내용의 형식을 명시적으로 지정하기 위해서는 PRINT 또는 PRINTF 문에서 FORMAT이라는 키워드를 사용해야 합니다. 그래서 적절한 형식을 담은 FORMAT 키워드를 사용하여 먼저 화면상에 출력을 해보기 위하여, 앞서 사용했던 PRINT가 포함된 반복문의 내용을 다음과 같이 수정해 봅시다.
FOR j = 0, N_ELEMENTS(player)-1 DO $
PRINT, player[j], ab[j], hit[j], bavg[j], $
FORMAT='(A3, 2X, I3, 2X, I3, 2X, F5.3)'
여기서는 컬럼간 간격을 두 칸으로 명시했고, 타율값이 소수점 세째 자리까지만 표시되도록 명시하였습니다. 이와 같이 FORMAT 키워드가 사용된 내용을 실행하여 얻은 출력 결과는 다음과 같습니다.
AAA 339 91 0.268
BBB 284 88 0.310
CCC 372 113 0.304
DDD 306 78 0.255
EEE 297 82 0.276
이러한 출력 결과가 충분히 만족스럽다면, 생성될 텍스트 파일도 동일한 내용을 담도록 수정해야 하겠지요. 앞서 PRINTF가 포함된 반복문의 내용을 다음과 같이 수정하면 됩니다. 이렇게 다시 생성된 bat_stat.txt 파일의 내용을 살펴보면 위와 같은 형태로 변경되어 있음을 확인할 수 있을 것입니다.
OPENW, lunw, 'bat_stat.txt', /GET_LUN
FOR j = 0, N_ELEMENTS(player)-1 DO $
PRINTF, lunw, player[j], ab[j], hit[j], bavg[j], $
FORMAT='(A3, 2X, I3, 2X, I3, 2X, F5.3)'
FREE_LUN, lunw
이번에는 다음과 같이 기존의 5명의 선수들 외에 추가로 전달된 2명의 선수들의 데이터가 또 있는 경우를 가정해 봅시다. 그래서 앞서 생성했던 bat_stat.txt 파일에 이 추가분의 데이터를 덧붙여야 한다면, 이것은 어떻게 처리해야 할까요?
player_add = ['FFF', 'GGG']
ab_add = [355, 263]
hit_add = [96, 70]
bavg_add = FLOAT(hit_add)/ab_add
사실 이러한 경우에도 작업의 기본적인 틀은 비슷합니다. 다만 이 경우에는 OPENW 명령을 사용하는데 있어서 키워드 하나가 추가로 필요한데, 바로 /APPEND 키워드입니다. 따라서, 기존에 생성되어 있는 bat_stat.txt 파일의 뒷 부분에 추가된 내용이 반영되도록 하려면, 파일 생성 부분의 프로그램을 다음과 같이 사용하면 됩니다.
OPENW, lunw, 'bat_stat.txt', /GET_LUN, /APPEND
FOR j = 0, N_ELEMENTS(player_add)-1 DO $
PRINTF, lunw, player_add[j], ab_add[j], hit_add[j], bavg_add[j], $
FORMAT='(A3, 2X, I3, 2X, I3, 2X, F5.3)'
FREE_LUN, lunw
보시면 아시겠지만, 전반적인 틀은 앞서 소개된 내용과 유사합니다. 다만 OPENW 명령에서 /APPEND 키워드가 추가적으로 사용된 것 뿐입니다. 이와 같은 내용을 실행하여 생성한 bat_stat.txt 파일의 내용을 실제로 보면 다음과 같습니다. 기존의 내용을 훼손하지 않고 유지하면서, 추가된 내용이 덧붙여진 모습을 확인할 수 있습니다.
AAA 339 91 0.268
BBB 284 88 0.310
CCC 372 113 0.304
DDD 306 78 0.255
EEE 297 82 0.276
FFF 355 96 0.270
GGG 263 70 0.266
만약 위 내용에서 /APPEND 키워드를 사용하지 않으면 어떻게 될까요? 아마 짐작이 가능하리라 생각이 되는데요. 다음과 같이 그냥 새로운 2명의 테이터만 달랑 반영된 파일이 생성됩니다.
FFF 355 96 0.270
GGG 263 70 0.266
즉, OPENW에서 /APPEND 키워드를 사용하지 않으면 무조건 새로운 파일로 생성한 후 거기에 내용이 쓰여지게 되기 때문입니다. 사실 이렇게 /APPEND 키워드를 사용하는 방식은 실전에서도 꽤 유용합니다. 예를 들어, 어떤 주기적으로 실행되는 IDL 프로그램에서 매 회차별 작업 내용을 하나의 텍스트 파일에 써서 일종의 작업 로그(Log) 파일을 만들어야 할 경우를 생각해볼 수 있습니다. 저 역시 실전에서 매우 유용하게 활용하고 있는 방법이기도 합니다.
오늘은 텍스트 파일을 쓰는 방법에 관한 얘기를 해 보았습니다. 이와 관련하여 아래 링크의 내용도 참조해 볼 만하여 소개해 봅니다. 이 내용은 IDL User 웹페이지에 소개된 내용으로서, OPENR/OPENW/OPENU에 관한 좀 더 폭넓은 내용을 담고 있습니다. IDL에서 파일의 입출력과 관련하여 참고해두면 좋을 내용이라고 생각합니다.
'IDL > Programming' 카테고리의 다른 글
| 포맷 코드 사용 관련 유용한 팁 하나 소개 (0) | 2017.07.10 |
|---|---|
| 인덱스 기반의 배열의 생성에 관하여 (0) | 2017.04.07 |
| Tex 형식의 특수 기호가 사용된 그림을 파일로 저장하는 방법 및 유의 사항 (0) | 2016.09.08 |
| 배열의 사용과 관련하여 유의해야 할 최근 변동사항 (0) | 2016.07.25 |
| SAVE 명령 및 IDL_SAVEFILE 클래스의 사용에 관하여 [1] (0) | 2016.06.22 |