728x90
작업을 하다보면 이름이 날짜 기반의 문자열로 이루어진 파일들을 갖고 작업을 해야 할 경우들이 꽤 자주 생깁니다. 예를 들면, 다음과 같은 이름을 갖는 파일을 생각해봅시다.
20110309_Gp_xr_1m.txt
만약에 위의 파일명과 같은 형식을 갖되 내가 원하는 날짜로 된 파일명을 만들고 싶다면 어떻게 하면 될까요? 예를 들어, 2010년 5월 14일에 해당되는 파일명을 문자열로 생성하고 싶다면 말입니다. 물론 아래와 같이 하면 되지않겠냐라고 하시면 그것도 꼭 틀린 대답은 아닐 수도 있습니다.
fn = '20100514_Gp_xr_1m.txt'
그런데 년월일이 숫자로 즉, 2010, 5, 14와 같은 값들만으로 주어지는 상황일 경우 또한 이러한 값들이 자주 바뀌어서 그때그때 즉각적으로 대응되는 파일명을 생성하도록 코딩을 해야한다면 다른 방법을 쓰는게 좋을겁니다. 이러한 경우에는 JULDAY라는 함수 그리고 STRING 함수의 FORMAT 키워드에서 날짜에 특화된 포맷코드를 사용해주면 됩니다. 따라서 다음과 같이 해봅시다.
tj = JULDAY(14, 5, 2010)
tt = STRING(tj, FORMAT='(C(CYI4.4, CMoI2.2, CDI2.2))')
여기서 JULDAY 함수에 들어가는 인자의 순서는 월, 일, 년, 시, 분, 초입니다. 이 함수로 산출되는 값은 Julian day에 해당되는 double형의 값이 됩니다. 그리고 이 값에 대하여 STRING 함수를 적용하여, Julian day를 날짜문자열로 변환합니다. 여기서 FORMAT 키워드에 지정된 포맷코드를 봅시다. CYI는 년도, CMoI는 월, CDI는 일에 해당됩니다. 그외에 여기는 안나와있지만 CHI는 시, CMI는 분, CSI는 초에 해당된다는 점을 참고로 알아두면 좋습니다. 각 포맷코드마다 4.4, 2.2와 같은 숫자가 있는데, 이는 4자리 숫자로 표현을 하되 자릿수가 비는 부분은 0으로 채워넣으라는 의미입니다. 따라서 CMoI2.2로 5월을 표시하면 '5'가 아닌 '05'가 됩니다. 이렇게 하지않으면 파일명 중간에 빈칸이 생기기 때문에, CMoI2가 아닌 CMoI2.2로 사용하는 것이 좋습니다. PRINT 명령을 사용하여 tt를 출력해보면 '20100514'라는 문자열이 출력되는 것을 확인할 수 있습니다.
이번에는 이와 유사한 형식의 이름을 갖는 파일들이 특정 폴더안에 여러개 있는 경우를 생각해봅시다. 아마 이와 같은 상황에서 작업을 해야하는 경우가 종종 있을겁니다. 예를 들어, 현재 작업 디렉토리안에 data/LASCO라는 하위폴더가 있고 이 안에 다음과 같이 JPG파일들이 모여있는 경우를 한번 살펴봅시다.
물론 실제 파일 갯수는 이 그림에 나온 것보다 훨씬 많습니다. 어쨌든 이 폴더안에는 날짜기반의 이름을 가진 JPG파일들이 여럿 있고, 파일명의 중간이 c2 또는 c3이라고 된 두 종류로 나눠진다라고 볼 수 있습니다. 먼저 이 폴더안에 있는 모든 파일의 파일명들만 뽑아보기 위하여 다음과 같이 FILE_SEARCH라는 함수를 이용해봅시다.
files = FILE_SEARCH('data/LASCO/*.*')
그러면 이 files는 이 폴더안에 있는 모든 파일들의 이름들로 이루어진 문자 배열이 됩니다. 물론 다음과 같이 맨끝의 확장자만 따로 명시하더라도 결과는 같을겁니다. 어차피 이 폴더안에 JPG파일밖에 없다면 말이죠.
files = FILE_SEARCH('data/LASCO/*.jpg')
이 상태에서 HELP 및 PRINT 명령을 files에 대해 사용해보면, 총 몇 개의 파일명들을 담고 있는지 그리고 각 파일명은 어떻게 되는지를 직접 확인할 수 있습니다. 저같은 경우 다음 그림과 같이 72개의 파일들이 있다는 결과가 나옵니다.
여기서 만약 파일명 중간에 'c2'가 들어가는 것들만 추리려면 어떻게 하면 될까요? 이러한 경우에는 와일드카드(*)를 잘 활용하여 다음과 같이 해주면 됩니다.
files = FILE_SEARCH('data/LASCO/*c2*.jpg')
이와 같이 와일드카드(*)를 잘 활용하면 여러가지 조건에 맞는 파일명들만 추출해낼 수 있다는 점을 참고해두시기 바랍니다. 이렇게 추출된 files에 대하여 HELP 및 PRINT를 해보니 제 경우는 다음과 같이 36개의 파일들이 있다는 결과를 얻었습니다.
지금 이렇게 'c2'라는 문자열이 들어간 파일들의 경우 시간의 범위가 2011년 3월 8일 18시 48분부터 3월 9일 02시 48분까지 8시간에 걸쳐있습니다. 만약 이 파일들중에서 2011년 3월 8일 20시 00분부터 22시 00분 사이에 해당되는 파일들만 추출하고 싶다면 어떻게 해야 할까요? 몇가지 방법들을 생각해볼 수는 있겠지만, 저는 다음과 같은 방법을 추천합니다. 일단 코드부터 적습니다.
tj1 = JULDAY(3, 8, 2011, 20, 0)
tj2 = JULDAY(3, 8, 2011, 22, 0)
fn1 = 'data/LASCO/' + STRING(tj1, FORMAT='(C(CYI4.4, CMoI2.2, CDI2.2))') + '_' + $
STRING(tj1, FORMAT='(C(CHI2.2, CMI2.2))') + '_c2_1024.jpg'
fn2 = 'data/LASCO/' + STRING(tj2, FORMAT='(C(CYI4.4, CMoI2.2, CDI2.2))') + '_' + $
STRING(tj2, FORMAT='(C(CHI2.2, CMI2.2))') + '_c2_1024.jpg'
PRINT, fn1
PRINT, fn2
ww = WHERE(files GE fn1 AND files LE fn2, count)
PRINT, count
PRINT, files[ww]
여기서 tj1과 tj2는 원하는 시간범위의 경계에 해당되는 시간을 Julian day로 환산한 것입니다. 그리고 fn1과 fn2는 이 tj1과 tj2에 대하여 STRING 함수를 활용하여 각 범위경계에 해당되는 파일명을 얻은 것입니다. 이 fn1, fn2를 출력해보면 각각 다음과 같이 나옵니다.
data/LASCO/20110308_2000_c2_1024.jpg
data/LASCO/20110308_2200_c2_1024.jpg
물론 이와 같은 이름의 파일이 실제로 data/LASCO 폴더안에 있을 수도 있고 없을 수도 있습니다. 다만 fn1과 fn2는 문자형태의 경계값이라고 보면 됩니다. 이 두 경계값을 뒤에 나오는 WHERE 함수에서 활용한 것입니다. 문자값도 GE, GT, LE, LT와 같은 연산자를 적용할 수 있습니다. 예를 들어, 'AB'와 'AC'를 비교하면 'AC'가 더 큰 값에 해당되고, 'AA03'과 'AA05'를 비교하면 'AA05'가 더 큰 값에 해당된다는 점을 이용한 것입니다. 그래서 files[ww]를 출력하면 정말 20시에서 22시라는 시간범위에 해당되는 8개의 파일들만 추출되었음을 확인할 수 있습니다.
날짜 기반의 이름으로 된 파일들을 다루고자 할 때 위와 같은 방법론을 기본으로 하여 각자의 상황에 맞게 적당히 응용을 하면, 매우 다양한 방식으로 파일들을 처리할 수 있는 여러가지 방법들이 나올 수 있을 것이라 생각됩니다.
LIST
'IDL > Programming' 카테고리의 다른 글
| 누적에 의한 배열 생성법 (0) | 2012.07.08 |
|---|---|
| 배열 합치기 (0) | 2012.05.04 |
| 키워드(keyword)와 인자(argument)에 관하여 (0) | 2012.01.13 |
| _EXTRA라는 키워드에 관하여 (0) | 2012.01.09 |
| COMPILE_OPT의 활용 (0) | 2011.12.13 |