sys_find_files Subroutine

public subroutine sys_find_files(directory, pattern, files, num_files, recursive, max_depth)

Find files matching a pattern (recursive or non-recursive)

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: directory
character(len=*), intent(in) :: pattern
character(len=*), intent(out) :: files(:)
integer, intent(out) :: num_files
logical, intent(in), optional :: recursive
integer, intent(in), optional :: max_depth

Source Code

   subroutine sys_find_files(directory, pattern, files, num_files, recursive, max_depth)
        character(len=*), intent(in) :: directory, pattern
        character(len=*), intent(out) :: files(:)
        integer, intent(out) :: num_files
        logical, intent(in), optional :: recursive
        integer, intent(in), optional :: max_depth
        character(len=1024) :: command, temp_file
        logical :: is_recursive
        integer :: depth, unit, iostat
        character(len=512) :: line

        is_recursive = .false.
        if (present(recursive)) is_recursive = recursive

        depth = 1
        if (present(max_depth)) depth = max_depth

        temp_file = create_temp_file('sys_find_found', '.tmp')

        if (get_os_type() == OS_WINDOWS) then
            if (is_recursive) then
              command = 'cmd /c dir /s /b "'//trim(escape_shell_arg(directory))//'\'// &
  trim(escape_shell_arg(pattern))//'" 2>nul > "'//trim(escape_shell_arg(temp_file))//'"'
            else
                command = 'cmd /c dir /b "'//trim(escape_shell_arg(directory))//'\'// &
  trim(escape_shell_arg(pattern))//'" 2>nul > "'//trim(escape_shell_arg(temp_file))//'"'
            end if
        else
            if (is_recursive) then
                command = 'find "'//trim(escape_shell_arg(directory))//'" -name "'//trim(escape_shell_arg(pattern))// &
                     '" -type f > "'//trim(escape_shell_arg(temp_file))//'" 2>/dev/null'
            else
                command = 'find "'//trim(escape_shell_arg(directory))//'" -maxdepth '
                write (command(len_trim(command) + 1:), '(I0)') depth
                command = trim(command)//' -name "'//trim(escape_shell_arg(pattern))// &
                     '" -type f > "'//trim(escape_shell_arg(temp_file))//'" 2>/dev/null'
            end if
        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_find_files