Selective Extraction

Purpose

This guide covers extracting specific files from an archive rather than all contents.

References

Concepts

Selective extraction allows you to extract only specific files from an archive, saving time and disk space when you only need certain files.

Basic Selective Extraction

Use the files option to specify which files to extract:

# Extract specific files
Excavate::Archive.new('data.tar.gz').extract(
  files: ['config/settings.json', 'data/users.csv']
)
# Returns: ["/path/to/config/settings.json", "/path/to/data/users.csv"]

Return Value

When using selective extraction, the return value is an array of extracted file paths instead of the target directory:

# Full extraction returns directory path
target = Excavate::Archive.new('archive.zip').extract
# => "/path/to/archive"

# Selective extraction returns file paths
files = Excavate::Archive.new('archive.zip').extract(files: ['readme.txt'])
# => ["/path/to/readme.txt"]

Nested Archive Paths

When extracting from nested archives, you can specify paths that include the nested archive name. The recursive_packages option is automatically enabled when using the files: option:

# Extract file from nested archive
Excavate::Archive.new('nested_archives.zip').extract(
  files: ['inner.zip/file.txt']
)

Multi-Level Nesting

Excavate supports arbitrary levels of nesting. For deeply nested archives:

# Extract from three levels deep
Excavate::Archive.new('bundle.zip').extract(
  files: ['level1.zip/level2.zip/level3.zip/file.txt']
)

How It Works

The path format is: nested_archive_name/path/to/file

Excavate will:

  1. Extract the outer archive

  2. Look for the specified nested archive by name

  3. Extract files from that nested archive matching the path

For multi-level nesting, the process repeats recursively.

Multiple Files

Extract multiple files at once:

files = Excavate::Archive.new('backup.tar').extract(
  files: [
    'etc/hosts',
    'etc/resolv.conf',
    'home/user/.bashrc'
  ]
)

With Recursive Extraction

Combine selective extraction with recursive extraction:

# Extract specific files from nested archives
Excavate::Archive.new('installer.msi').extract(
  files: [
    'fonts.zip/Arial.ttf',
    'fonts.zip/Verdana.ttf'
  ]
)
The recursive_packages option is automatically enabled when using the files: option. You can still specify it explicitly if needed.

Error Handling

If a specified file is not found:

begin
  Excavate::Archive.new('data.zip').extract(files: ['missing.txt'])
rescue Excavate::TargetNotFoundError => e
  puts "File not found: #{e.message}"
  # => "File `missing.txt` not found."
end

Finding File Paths

To discover what files are available in an archive:

# List all files in an archive
Excavate::Archive.new('archive.zip').files(recursive_packages: true) do |path|
  puts path
end

Or use the CLI:

# Extract and list to see structure
excavate -r archive.zip

# Then search
find archive -name "*.conf"

CLI Usage

Extract specific files from the command line:

# Extract specific files
excavate data.tar.gz config/settings.json data/users.csv

# Extract from nested archive
excavate -r installer.msi fonts.zip/Arial.ttf

Performance Benefits

Selective extraction is more efficient when you only need certain files:

  • Faster extraction (fewer files to process)

  • Less disk space used

  • Reduced I/O operations

# Instead of extracting everything
Excavate::Archive.new('large.tar.gz').extract  # Slow, large

# Extract only what you need
Excavate::Archive.new('large.tar.gz').extract(
  files: ['config.json']  # Fast, small
)

Common Patterns

Extract Configuration Files

config_files = Excavate::Archive.new('backup.tar').extract(
  files: [
    'etc/nginx/nginx.conf',
    'etc/mysql/my.cnf',
    'etc/redis/redis.conf'
  ]
)

Extract Font Files from Installer

# First, find available fonts
fonts = []
Excavate::Archive.new('fonts.msi').files(recursive_packages: true) do |path|
  fonts << path if path.end_with?('.ttf')
end

# Then extract them (recursive_packages auto-enabled with files:)
Excavate::Archive.new('fonts.msi').extract(
  files: fonts
)

Next Steps