Search code examples
ruby-on-railspattern-matchingsftpnet-sftp

Multiple file pattern for Net::SFTP in rails


In my rails application, i'm connecting to SFTP and downloading files based on a pattern. My code looks like this:

require 'net/sftp'

...

Net::SFTP.start(host, user, config) do |sftp|
 Rails.logger.info "Connected to sftp"
 sftp.dir.glob(@file_path, @file_regex) do |file|
 ...
 end
end

I need to download xlsx and csv files. Below is the function for fetching the @file_regex:

def fetch_sftp_file_format
 ist_timezone = TZInfo::Timezone.get('Asia/Kolkata')
 current_date = Time.now.in_time_zone(ist_timezone).strftime('%Y_%m_%d')
 "*_#{current_date}.xlsx"
end

This code is working fine, but i'm not able to set the pattern for xlsx and csv file together. Pattern for all the file types "*_#{current_date}.*" is also working.

I tried "*_#{current_date}.(xlsx|csv)", "*_#{current_date}.(xlsx|csv)$", "*_#{current_date}.{xlsx,csv}" but these aren't working.

net-sftp gem version: 4.0.0


Solution

  • The Docs are a bit misleading where they state "Works as ::Dir.glob" instead they should read "Works as ::File.fnmatch"

    The Net::SFTP library uses File::fnmatch for Operations::Dir#glob.

    According to the Docs for File::fnmatch.

    The pattern is not a regular expression; instead it follows rules similar to shell filename globbing. It may contain the following metacharacters:...

    {a,b}

    Matches pattern a and pattern b if File::FNM_EXTGLOB flag is enabled. Behaves like a Regexp union ((?:a|b)).

    So it appears you need to change the pattern to:

    "*_#{current_date}.{xlsx,csv}"
    

    and enable the appropriate flags:

    sftp.dir.glob(@file_path, @file_regex,File::FNM_EXTGLOB)