Converting Between DBM Files (Perl Cookbook, 2nd Edition)

## 14.3. Converting Between DBM Files

### 14.3.1. Problem

You have a file in one DBM format, but another program expects input in a different DBM format.

### 14.3.2. Solution

Read the keys and values from the initial DBM file and write them to a new file in the different DBM format as in Example 14-2.

#### Example 14-2. db2gdbm

>       #!/usr/bin/perl -w
>       # db2gdbm: converts DB to GDBM

>       use strict;

>       use DB_File;
>       use GDBM_File;

>       unless (@ARGV =  = 2) {
>           die "usage: db2gdbm infile outfile\n";
>       }

>       my ($infile, $outfile) = @ARGV;
>       my (%db_in, %db_out);

>       # open the files
>       tie(%db_in, 'DB_File', $infile)
>           or die "Can't tie $infile: $!";
>       tie(%db_out, 'GDBM_File', $outfile, GDBM_WRCREAT, 0666)
>           or die "Can't tie $outfile: $!";

>       # copy (don't use %db_out = %db_in because it's slow on big databases)
>       while (my($k, $v) = each %db_in) {
>           $db_out{$k} = $v;
>       }

>       # these unties happen automatically at program exit
>       untie %db_in;
>       untie %db_out;

Call the program as:

>     % db2gdbm /tmp/users.db /tmp/users.gdbm

### 14.3.3. Discussion

When multiple types of DBM file are used in the same program, you have to use `tie`, not the `dbmopen` interface. That's because with `dbmopen` you can use only one database format, which is why its use is deprecated.

Copying hashes by simple assignment, as in `%new` `=` `%old`, works on DBM files. However, it loads everything into memory first as a list, which doesn't matter with small hashes, but can be prohibitively expensive in the case of DBM files. For database hashes, use `each` to iterate through them instead.

### 14.3.4. See Also

The documentation for the standard modules GDBM_File, NDBM_File, SDBM_File, DB_File, some of which are in Chapter 32 of Programming Perl; Recipe 14.1

Copyright © 2003 O'Reilly & Associates. All rights reserved.