List files in a directory matching a pattern
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
character(len=*), | intent(in) | :: | directory | |||
character(len=*), | intent(in) | :: | pattern | |||
character(len=*), | intent(out) | :: | files(:) | |||
integer, | intent(out) | :: | num_files |
subroutine sys_list_files(directory, pattern, files, num_files) character(len=*), intent(in) :: directory, pattern character(len=*), intent(out) :: files(:) integer, intent(out) :: num_files character(len=512) :: command, temp_file integer :: unit, iostat character(len=512) :: line temp_file = create_temp_file('sys_list_files', '.tmp') if (get_os_type() == OS_WINDOWS) then ! For Windows cmd /c, we need to handle quotes specially ! Using ^ to escape quotes inside the cmd /c string command = 'cmd /c dir /b "'//trim(escape_shell_arg(directory))//sys_get_path_separator()// & trim(escape_shell_arg(pattern))//'" 2>nul > "'//trim(escape_shell_arg(temp_file))//'"' else command = 'ls "'//trim(escape_shell_arg(directory))//sys_get_path_separator()// & trim(escape_shell_arg(pattern))//'" 2>/dev/null > "'//trim(escape_shell_arg(temp_file))//'"' end if call execute_command_line(command) num_files = 0 open (newunit=unit, file=temp_file, status='old', iostat=iostat) if (iostat == 0) then do read (unit, '(A)', iostat=iostat) line if (iostat /= 0) exit if (num_files < size(files)) then num_files = num_files + 1 ! Both dir /b and ls might return just filenames, so always prepend directory if (index(line, '/') == 0 .and. index(line, '\') == 0) then ! Line contains just filename, prepend directory if (get_os_type() == OS_WINDOWS) then files(num_files) = trim(directory)//'\'//trim(line) else files(num_files) = trim(directory)//'/'//trim(line) end if else ! Line already contains full path files(num_files) = trim(line) end if end if end do close (unit) end if call sys_remove_file(temp_file) end subroutine sys_list_files