MARC::Loop - process a batch of MARC21 records


    use MARC::Loop qw(marcloop marcbuild TAG VALREF DEL);
    my $filehandle = \*STDIN;
    my $deleted999 = 0;
    my $fixed035 = 0;
    marcloop {
        my ($leader, $fields, $raw_marc_ref) = @_;
        my $changed;
        foreach my $field (@$fields) {
            if ($field->[TAG] eq '035') {
                # Normalize OCLC numbers
                my $valref = $field->[VALREF];
                $$valref =~ s/\(OCoLC\)oc[mn]0*/(OCoLC)/g;
                $changed = 1;
            elsif ($field->[TAG] eq '999') {
                # Delete 999 fields
                $field->[DEL] = 1;
                $changed = 1;
        # Print only changed records
        print marcbuild($leader, $fields) if $changed;
    } $filehandle;
    print STDERR "$deleted999 999 fields were deleted\n",
                 "$fixed035 035 fields were fixed\n";


MARC::Loop is an alternative to MARC::File and MARC::Record that eschews an object-oriented approach in favor of a bare-bones procedural one.


All of these functions are exported upon request.


    # This example prints a MARC record in human-readable form, using a single
    # line for each field no matter how many subfields it might have.
    use MARC::Loop qw(marcloop);
    marcloop {
        my ($leader, $fields, $raw_marc_ref) = @_;
        foreach my $field (@$fields) {
            if ($field->[TAG] lt '010) {
                # Control field
                my $valref = $field->[VALREF];
                print $field->[TAG], '    ', $$valref, "\n";
            else {
                # Data field 
                my ($i1, $i2) = ($field->[IND1], $field->[IND2]);
                print "$field->[TAG] $i1$i2";
                my @subfields  = @{ $field->[SUBS..$#$field] };
                foreach my $subfield (@subfields) {
                    my ($code, $valref) = @$subfield;
                    print '$', $code, ' ', $$valref;
                print "\n";
    } $filehandle, %options;


All MARC records will be printed to STDOUT. Any changes you make will be reflected in what is printed.

drop array_ref
    'drop' => [ '001', '090' ]

Tags of fields to be dropped unconditionally.

only array_ref
    'only' => [ qw(001 004 008 852 856) ]

Tags of fields to be preserved; all other fields will be dropped. (The leader is never dropped, of course.)


A code reference to call when there is an error.

    'error' => sub { exit -1 }
    'strict' => 1

Halt processing when an ill-formed MARC record is encountered.

Options will be more fully documented in a future release; in the meantime, read the source code.


    ($leader, $fields) = marcparse(\$string, %options);

Parses a MARC record into the same data structure that marcloop uses. Options are mostly the same as for marcloop.


    print marcbuild($leader, $fields);

Builds a raw MARC record from the same data structure that marcloop uses and that marcparse produces.


    # Control field
    push $@fields, marcfield(                  
        '001',   # Tag
        1234567, # Content

    # Data field
    push $@fields, marcfield(                  
        '245',              # Tag
        ' ', ' ',           # Indicators
        'a' => 'Blah blah', # Subfield $a
        'c' => 'Amy Emu',   # Subfield $c
        ...                 # More subfields

A convenience function to build a data structure representing a single MARC21 field.


The documentation is woefully lacking and probably just plain wrong. Read the source code -- or, better yet, step through it in the Perl debugger -- to get a better understanding of what this code does.

Unhandled errors cause ill-formed records to be dropped without notice. You must specify an error option to marcloop to get around this.


Paul Hoffman <>.


Copyright 2009-2010 Fenway Libraries Online. Released under the GNU Public License, version 3.