IDL/Programming

날짜 기반의 이름을 갖는 파일들에 대한 접근법

이상우_IDL 2025. 7. 1. 14:28
728x90

우리가 IDL에서 파일들을 대상으로 작업을 할 때 파일의 이름에 날짜 기반의 문자열이 포함된 경우가 종종 있습니다. 예를 들면, 다음과 같은 이름을 갖는 파일을 가정해봅시다.

 

20250603_181500_Ic_flat_4k.jpg

 

이것은 실제로 배포되고 있는 파일로서, 그 관측시각이 2025년 6월 3일 18시 15분 00초인 JPG 파일입니다. 그런데 만약 유저가 원하는 특정한 날짜에 대하여 위와 같은 형식을 갖는 파일명을 직접 문자로 생성하려면 어떻게 하면 될까요? 예를 들어서 2025년 6월 7일 13시 30분에 해당되는 파일명을 위와 같은 형식의 문자열로 생성하려는 경우입니다. 이러한 작업을 위해서는 기본적으로는 JULDAY 함수 및 STRING 함수를 사용하면 됩니다. 그리고 STRING 함수의 FORMAT 키워드도 추가로 사용하여 날짜의 형식에 특화된 포맷코드를 명시해주는 것도 필요합니다. 이러한 작업은 일단 다음과 같이 시작합니다.

IDL> tj = JULDAY(6, 7, 2025, 13, 30)
% Compiled module: JULDAY.

IDL> PRINT, tj
       2460834.1


일단 JULDAY 함수 및 날짜 특화 포맷 등에 관해서는 기존에 올렸던 관련 게시물들(링크1, 링크2)의 내용을 참조해보시기 바랍니다. 기본적으로 JULDAY 함수에 투입되는 인자들의 순서는 월, 일, 년, 시, 분, 초입니다. 그리고 JULDAY 함수에 의하여 산출되는 결과는 줄리안 날짜(Julian Date)에 해당되는 2배 정밀도(Double Precision) 실수 자료형의 값이 됩니다. 그런데 위의 내용에서 JULDAY 함수에 의하여 얻은 tj의 값은 줄리안 날짜이기 때문에 이 값 자체는 우리가 날짜로서 쉽게 인지할 수 있는 상태는 아닙니다. 위에서 PRINT에 의하여 출력된 tj의 값을 보면 쉽게 확인할 수 있습니다. 따라서 JULDAY 함수로 얻은 결과인 tj에 대하여 STRING 함수를 적용함으로써 우리가 알아볼 수 있는 날짜 형태의 문자값으로 변환하는 것이 필요합니다. 이 때 STRING 함수를 FORMAT 키워드와 함께 사용해야 합니다. 그러한 과정을 보면 대략 다음과 같습니다.

 

IDL> tt = STRING(tj, FORMAT='(C(CYI4.4, CMoI2.2, CDI2.2, "_", CHI2.2, CMI2.2, CSI2.2))')
IDL> PRINT, tt
20250607_133000
IDL> fname = tt+'_Ic_flat_4k.jpg'
IDL> PRINT, fname
20250607_133000_Ic_flat_4k.jpg

 

위의 STRING 함수가 사용된 내용에서 FORMAT 키워드에 부여된 포맷코드를 보면 CYI는 년도(Year), CMoI는 월(Month), CDI는 일(Day), CHI는 시(Hour), CMI는 분(Minute), CSI는 초(Second)에 해당됩니다. 그리고 각 포맷코드마다 4.4, 2.2와 같은 숫자가 있는데, 이는 4자리 숫자로 표현을 하면서 자릿수가 비는 부분은 0으로 채워넣으라는 의미입니다. 따라서 CMoI2.2로 5월을 표시하면 '5'가 아닌 '05'가 됩니다. 만약 이렇게 하지 않으면 파일명 중간에 빈칸이 생기기 때문에 반드시 CMoI2가 아닌 CMoI2.2로 처리해야 합니다. 그 외에도 년월일과 시분초 문자 사이에 "_" 문자가 삽입되도록 하였습니다. 이러한 과정을 거쳐서 얻은 문자값을 담은 변수 tt를 PRINT 명령으로 출력한 내용을 보면 '20250607_133000'라는 문자열이 출력되는 것을 확인할 수 있습니다. 그리고 맨 처음에 제시했던 파일명과 동일한 형식의 문자값을 얻기 위하여 tt에 뒷부분 문자열까지 더한 결과를 변수 fname에 담는 과정까지 수행하면 우리가 원했던 결과에 해당되는 문자값을 얻게 됩니다. 위에서 변수 fname의 값을 출력한 내용을 보면 이를 확인할 수 있습니다.

 

그러면 이번에는 이와 동일한 형식의 이름을 갖는 다수의 파일들이 유저의 PC 내에서 특정한 폴더 안에 존재하는 경우를 살펴봅시다. 실제로 이와 같은 상황에서 다수의 파일들에 접근하면서 작업을 해야하는 경우가 종종 있습니다. 예를 들어서 유저의 PC에 C:\data라는 폴더가 있고 이 안에 다음과 같이 다수의 JPG파일들이 모여있는 경우를 한번 가정해봅시다. 그러한 실제 예제로서 제 PC에서 이러한 상황을 캡쳐해본 모습은 다음과 같습니다.

 

 

이와 같이 특정한 폴더 내에 날짜 기반의 이름을 가진 다수의 JPG 파일들이 존재하는 상태입니다. 참고로 PC의 OS 설정에 따라서는 파일의 이름을 보여줄 때 확장자를 숨기도록 설정되어 있는 경우가 종종 있는데, 위의 스크린샷도 그러한 경우입니다. 실제로는 모든 파일들의 이름은 확장자인 .jpg로 끝납니다. 어쨌든 먼저 이 폴더 내에 있는 모든 파일들의 목록을 추출해봅시다. 이러한 작업을 위해서는 다음과 같이 FILE_SEARCH 함수를 이용하면 됩니다.

 

IDL> files = FILE_SEARCH('C:\data\*.*')
IDL> HELP, files
FILES           STRING    = Array[626]

 

여기서는 FILE_SEARCH 함수를 이용하여 C:\data 폴더 내에 존재하는 모든 파일들의 이름들을 files라는 배열로 추출하였습니다. 이 때 탐색 대상이 될 파일의 이름을 *.*와 같이 표기한 것을 주목해야 합니다. 즉 탐색 대상이 될 파일들의 이름을 명시할 때 와일드카드 기호인 *를 적절히 활용하는 것이 필요할 수도 있다는 것을 염두에 둘 필요가 있습니다. 이렇게 얻어진 files는 해당 폴더 내에 존재하는 모든 파일들의 이름들로 구성된 문자형 배열이 됩니다. 만약 FILE_SEARCH 함수를 사용할 때 다음과 같이 맨끝의 확장자인 jpg를 직접 명시하더라도 결과는 같을 것입니다. 어차피 이 폴더 내에 오직 JPG 파일밖에 없다면 말이죠.

 

IDL> files = FILE_SEARCH('C:\data\*.jpg')

 

위에서 HELP에 의하여 출력된 내용을 보면 지정된 폴더 내에 총 626개의 파일들이 존재하는 것으로 확인됩니다(물론 제 PC에서 그렇다는 얘기입니다). 여기서 파일들의 목록이 제대로 얻어진 것인지 확인하기 위하여 다음과 같이 PRINT 명령을 반복형 구문과 함께 사용해봅시다.


IDL> FOR j = 0, N_ELEMENTS(files)-1 DO PRINT, files[j]

 

실제로 출력된 내용의 일부만 보면 다음과 같습니다.

 

C:\data\20250602_111500_Ic_flat_4k.jpg
C:\data\20250602_113000_Ic_flat_4k.jpg
C:\data\20250602_114500_Ic_flat_4k.jpg
C:\data\20250602_120000_Ic_flat_4k.jpg
C:\data\20250602_121500_Ic_flat_4k.jpg
C:\data\20250602_123000_Ic_flat_4k.jpg
C:\data\20250602_124500_Ic_flat_4k.jpg
C:\data\20250602_130000_Ic_flat_4k.jpg
C:\data\20250602_131500_Ic_flat_4k.jpg
C:\data\20250602_133000_Ic_flat_4k.jpg

 

이와 같이 FILE_SEARCH 함수에 의한 탐색 결과에서는 각 파일의 이름이 파일명 자체 뿐 아니라 폴더 경로까지 모두 포함하는 문자값이 된다는 것을 유의해야 합니다. 실제로 제 PC에서 얻은 이 파일들의 목록에서는 대략 6월 2일부터 6월 8일까지 정도의 기간 동안의 파일들이 함께 존재하는 상태입니다. 그런데 앞서 했던 것처럼 탐색 대상이 될 파일명을 *.*으로 명시하여 폴더 내의 모든 파일들을 대상으로 할 수도 있지만, 그 대신 특정한 하루만을 대상으로 할 경우도 있습니다. 예를 들어 6월 4일의 파일들만을 대상으로 해야 한다면 어떻게 하면 될까요? 이러한 경우에는 다음과 같이 와일드카드 기호(*)를 적절히 활용하면서 FILE_SEARCH 함수를 이용하면 됩니다.

 

IDL> files = FILE_SEARCH('C:\data\*0604*.jpg')

 

즉 이와 같이 파일명 내에 6월 4일을 뜻하는 0604라는 문자열이 존재하는 경우들만 추출하도록 하면 됩니다. 실제로 결과를 확인해보면 다음과 같습니다.

 

IDL> HELP, files
FILES           STRING    = Array[96]
IDL> FOR j = 0, N_ELEMENTS(files)-1 DO PRINT, files[j]
C:\data\20250604_000000_Ic_flat_4k.jpg
C:\data\20250604_001500_Ic_flat_4k.jpg
C:\data\20250604_003000_Ic_flat_4k.jpg
C:\data\20250604_004500_Ic_flat_4k.jpg
C:\data\20250604_010000_Ic_flat_4k.jpg
C:\data\20250604_011500_Ic_flat_4k.jpg
C:\data\20250604_013000_Ic_flat_4k.jpg
C:\data\20250604_014500_Ic_flat_4k.jpg

 

이와 같이 해당 파일들이 총 96개인 것으로 확인됩니다. 물론 PRINT 명령으로 출력된 파일 목록의 경우 위에서는 전체가 아닌 일부만 제시하였습니다. 어쨌든 FILE_SEARCH 함수를 사용하면서 와일드카드 기호(*)를 적절히 활용하면 유저의 필요에 따라 다양한 조건에 부합하는 파일목록을 추출할 수 있습니다.

 

이번에는 탐색하고자 하는 파일들의 날짜 범위를 좀 더 구체적으로 제한해봅시다. 예를 들어서 앞서 확인했던 전체 파일들 중에서 2025년 6월 7일 20시 00분부터 6월 8일 08시 00분 사이에 해당되는 파일들만 추출하고 싶다면 어떻게 해야 할까요? 나름 적절해보이는 방안을 하나 제시해본다면 그 과정은 다음과 같습니다.

 

files = FILE_SEARCH('C:\data\*.jpg')
tj1 = JULDAY(6, 7, 2025, 20, 0)
tj2 = JULDAY(6, 8, 2025, 8, 0)

fn1 = 'C:\data\'+STRING(tj1, FORMAT='(C(CYI4.4, CMoI2.2, CDI2.2, "_", CHI2.2, CMI2.2, CSI2.2))')+'_Ic_flat_4k.jpg'
fn2 = 'C:\data\'+ STRING(tj2, FORMAT='(C(CYI4.4, CMoI2.2, CDI2.2, "_", CHI2.2, CMI2.2, CSI2.2))')+'_Ic_flat_4k.jpg'
PRINT, fn1
PRINT, fn2

여기서 tj1과 tj2는 원하는 날짜 범위의 하한 및 상한에 해당되는 날짜를 JULDAY 함수를 사용하여 줄리안 날짜(Julian Day)로 환산한 것입니다. 그리고 fn1과 fn2는 각각 tj1과 tj2에 대하여 STRING 함수를 사용하여 날짜 범위의 하한 및 상한에 해당되는 파일명을 문자값으로 얻은 것입니다. 이렇게 얻은 fn1, fn2의 값을 출력해보면 각각 다음과 같습니다.

C:\data\20250607_200000_Ic_flat_4k.jpg

C:\data\20250608_080000_Ic_flat_4k.jpg

 

물론 이와 같은 이름의 파일들이 실제로 C:\data 폴더 내에 있을 수도 있고 없을 수도 있습니다. 다만 fn1과 fn2는 문자의 형태로 정의된 하한값 및 상한값으로 활용하는 것이 그 목적입니다. 즉 다음과 같이 WHERE 함수에 이 값들을 투입하여 탐색의 범위를 설정하면 됩니다.

 

ww = WHERE(files GE fn1 AND files LE fn2, count)
PRINT, count

files_ext = files[ww]

 

참고로 문자값에 대해서도 GE, GT, LE, LT 등과 같은 비교 연산자들을 사용할 수 있습니다. 예를 들어, 'AB'와 'AC'를 비교하면 'AC'가 더 큰 값에 해당되고, 'AA03'과 'AA05'를 비교하면 'AA05'가 더 큰 값에 해당된다는 점을 이용한 것입니다. 일단 이렇게 설정된 범위에 해당되는 파일들의 갯수를 count 변수에 담고 출력하도록 했는데 실제로 그 값은 49로 산출되었습니다. 이러한 49개의 파일들의 목록은 별도로 files_ext라는 이름으로 따로 추려내었습니다. 이렇게 탐색된 파일들의 이름을 순서대로 출력해보기 위하여 다음과 같이 적절한 반복형 구문을 사용해봅시다.

 

FOR j = 0, count-1 DO PRINT, files_ext[j]

 

그러면 처음에 주어진 날짜 범위에 해당되는 파일들만 정확히 추출되었음을 확인할 수 있습니다. 제가 실제로 얻은 출력 결과는 다음과 같습니다(일부가 아닌 전체 목록입니다).

 

C:\data\20250607_200000_Ic_flat_4k.jpg
C:\data\20250607_201500_Ic_flat_4k.jpg
C:\data\20250607_203000_Ic_flat_4k.jpg
C:\data\20250607_204500_Ic_flat_4k.jpg
C:\data\20250607_210000_Ic_flat_4k.jpg
C:\data\20250607_211500_Ic_flat_4k.jpg
C:\data\20250607_213000_Ic_flat_4k.jpg
C:\data\20250607_214500_Ic_flat_4k.jpg
C:\data\20250607_220000_Ic_flat_4k.jpg
C:\data\20250607_221500_Ic_flat_4k.jpg
C:\data\20250607_223000_Ic_flat_4k.jpg
C:\data\20250607_224500_Ic_flat_4k.jpg
C:\data\20250607_230000_Ic_flat_4k.jpg
C:\data\20250607_231500_Ic_flat_4k.jpg
C:\data\20250607_233000_Ic_flat_4k.jpg
C:\data\20250607_234500_Ic_flat_4k.jpg
C:\data\20250608_000000_Ic_flat_4k.jpg
C:\data\20250608_001500_Ic_flat_4k.jpg
C:\data\20250608_003000_Ic_flat_4k.jpg
C:\data\20250608_004500_Ic_flat_4k.jpg
C:\data\20250608_010000_Ic_flat_4k.jpg
C:\data\20250608_011500_Ic_flat_4k.jpg
C:\data\20250608_013000_Ic_flat_4k.jpg
C:\data\20250608_014500_Ic_flat_4k.jpg
C:\data\20250608_020000_Ic_flat_4k.jpg
C:\data\20250608_021500_Ic_flat_4k.jpg
C:\data\20250608_023000_Ic_flat_4k.jpg
C:\data\20250608_024500_Ic_flat_4k.jpg
C:\data\20250608_030000_Ic_flat_4k.jpg
C:\data\20250608_031500_Ic_flat_4k.jpg
C:\data\20250608_033000_Ic_flat_4k.jpg
C:\data\20250608_034500_Ic_flat_4k.jpg
C:\data\20250608_040000_Ic_flat_4k.jpg
C:\data\20250608_041500_Ic_flat_4k.jpg
C:\data\20250608_043000_Ic_flat_4k.jpg
C:\data\20250608_044500_Ic_flat_4k.jpg
C:\data\20250608_050000_Ic_flat_4k.jpg
C:\data\20250608_051500_Ic_flat_4k.jpg
C:\data20250608_053000_Ic_flat_4k.jpg
C:\data\20250608_054500_Ic_flat_4k.jpg
C:\data\20250608_060000_Ic_flat_4k.jpg
C:\data\20250608_061500_Ic_flat_4k.jpg
C:\data\20250608_063000_Ic_flat_4k.jpg
C:\data\20250608_064500_Ic_flat_4k.jpg
C:\data\20250608_070000_Ic_flat_4k.jpg
C:\data\20250608_071500_Ic_flat_4k.jpg
C:\data\20250608_073000_Ic_flat_4k.jpg
C:\data\20250608_074500_Ic_flat_4k.jpg
C:\data\20250608_080000_Ic_flat_4k.jpg

 

이와 같이 원하는 파일들의 목록 정보를 확보했다면 그 다음에는 각각의 파일에 대하여 구체적인 작업을 시작하면 됩니다. 예를 들어서 앞서 탐색된 49개의 파일들 중에서 10번째 파일에 대하여 뭔가 작업을 해본다면 대략 다음과 같을 것 같습니다. 대상 파일들이 JPG 형식의 그림 파일들임을 감안하여, 적절한 크기의 그래픽창을 띄우고 이미지로 표출하도록 해본 것입니다.

 

READ_JPEG, files_ext[9], img
win = WINDOW(DIMENSIONS=[1024, 1024], /NO_TOOLBAR)
i = IMAGE(img, MARGIN=0, /CURRENT)

 

어쨌든 날짜 기반의 이름을 가지는 다수의 파일들을 대상으로 작업을 해야 할 경우에는 위와 같은 방법론을 기본으로 하여 유저 각자의 상황에 맞게 적당히 응용을 하면 될 것 같습니다. 그리고 위의 예제는 윈도우즈 PC에 파일들이 존재하는 경우이기 때문에 파일들의 위치 경로가 'C:\data\*.jpg'와 같은 방식으로 명시가 되었는데요. 리눅스나 Mac OS 등과 같은 머신의 경우는 디렉토리 경로를 표시할 때 '\' 대신 '/' 기호를 사용합니다. 따라서 위치 경로가 예를 들면 '/document/myidl/data/*.jpg'와 같은 방식으로 명시되어야 할 것입니다. 결국 사용중인 PC의 OS 특성에 맞게 디렉토리 경로를 표시하면 된다는 점을 유의하면 됩니다.

 

 

* 이 내용은 지난 2011년에 올렸던 게시물의 내용을 보강할 뿐 아니라 완전히 대체할 목적으로 작성되었습니다. 따라서 기존의 게시물은 삭제하였습니다.

 

* 이 글이 도움이 되었다면 게시물에 대하여 공감 버튼(하트 모양) 클릭 및 블로그 구독도 해주시면 더 큰 힘이 됩니다. 감사합니다.

LIST