Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

This project provides a toolkit for efficiently processing bibliographic records encoded in MARC 21, which is a popular file format used to exchange bibliographic data between libraries. In particular, the command line tool marc21 allows efficient filtering of records and extraction of data into a rectangular schema. Since the extracted data is in tabular form, it can be processed with popular frameworks such as Polars or Tidyverse.

marc21-rs is developed by the Metadata Department of the German National Library (DNB). It is used for data analysis and for automating metadata workflows (data engineering) as part of automatic content indexing.

The source code is licensed under the European Union Public License 1.2.

Getting Started

Installation

Binaries

In order to install the marc21 binary, archives with a precompiled binary are available for Windows, macOS and Linux.

Two variants are available for Linux: a dynamically linked version and a fully statically linked version (MUSL). In most cases, the statically linked version should be preferred, as it is independent of the glibc version of the host system. The following commands install the binary into the /usr/local/bin directory:

$ tar xfz marc21-0.5.0-x86_64-unknown-linux-musl.tar.gz
$ sudo install -Dm755 marc21-0.5.0-x86_64-unknown-linux-musl/marc21 \
   /usr/local/bin/marc21

From Source

If a Rust toolchain is available, marc21 can also be installed using the Rust package manager cargo. The project requires a Rust compiler with a minimum version of 1.93. Use the following command to install the program with the default features:

$ cargo install marc21-cli  

The binary can be built with the following features as needed:

build
Commands and functions that are only needed during the build process or packaging are activated with the build feature. This includes, for example, the commands for generating man pages (build-man) and shell completions (build-completion).
performant
This feature activates optimizations aimed at improving performance. This includes, for example, the activation of SIMD or a more aggressive inline strategy. Since the main goal of the project is high performance, the feature is enabled by default.
unstable
New features that are still in the testing phase can be activated using the unstable feature. Keep in mind that these functions may change at any time.

First Steps

This section provides an overview of working with the marc21 command line tool. It demonstrates important commands using simple use cases. An in-depth explanation of the concepts, in particular the structure of filter expressions, has been omitted for brevity.

The marc21 tool provides various commands for processing MARC 21 records (see marc21 --help for a complete list of available commands).

Concatenate Multiple Files

The concat command can be used to combine multiple files into a single output. In the following example, the authority data files from the Integrated Authority Files (GND) are concatenated into the single file GND.mrc.gz.

$ marc21 concat -ps authorities-gnd-*.mrc.gz -o GND.mrc.gz
10,122,437 records, 0 invalid | 49,035 records/s, elapsed: 00:03:19

The --skip-invalid (-s) option is used to skip invalid records that could not be decoded. If the option is not specified, processing will abort at the first invalid record. In addition, the processing progress can be displayed with the --progress (-p) option.

Filtering Records

The filter command extracts those records that fulfill a specified condition. For example, all records with status z and at least one field 100 with indicators 1 and # (space) can be filtered as follows:

$ marc21 filter -s 'ldr.status == "z" && 100/1#?' DUMP.mrc.gz -o out.mrc

Operators

The comparison operators ==, !=, >=, >, <=, and < can be used for values in selected leader fields, values in control fields, and values in subfields. Here are a few examples

$ marc21 filter -s '100/1#.a == "Lovelace, Ada"' DUMP.mrc.gz -o out.mrc
$ marc21 filter -s '100/*.a != "Curie, Marie"' DUMP.mrc.gz -o out.mrc
$ marc21 filter -s '001 == "119232022"' DUMP.mrc.gz -o out.mrc
$ marc21 filter -s 'ldr.length > 3000' DUMP.mrc.gz -o out.mrc
$ marc21 filter -s 'ldr.status == "z"' DUMP.mrc.gz -o out.mrc

To check whether a value (control field or data field) comes from a specified list, the in operator is used. In contrast, the not in operator checks whether a value is not contained in the list. The following example tests whether a field 100 exists that has a subfield a with the value “Curie, Marie” or “Lovelace, Ada”:

$ marc21 filter -s '100/*.a in ["Lovelace, Ada", "Curie, Marie"]' \
    DUMP.mrc.gz -o out.mrc

The =? operator and, in negated form, !? perform a substring search on subfield values. These operators allow simultaneous searching for multiple patterns by using the []-notation:

$ marc21 filter -s '100/*.a =? ["Hate", "Love"]' DUMP.mrc.gz -o out.mrc.gz
$ marc21 filter -s '100/1#.a =? "Love"' DUMP.mrc.gz -o out.mrc.gz

Subfield values can be checked against one or a set of regular expressions. The filter expression uses the =~ operator or the !~ operator in negated form. The underlying regex engine does not support all regex features; please refer to the specification to learn more about the syntax and possible limitations. The following example searches for all records with a field 533 that contains a subfield n whose value matches the regular expression for an ISBN.

$ marc21 filter -s \
    '533.n =~ "(?i)ISBN(?:-1[03])?(?::?\\s*)?\\s(?:97[89][-\ ]?)?\\d{1,5}[-\\ ]?(?:\\d+[-\\ ]?){2}(?:\\d|X)"' \
    DUMP.mrc.gz -o out.mrc.gz

To test whether a subfield value begins with a prefix or not, the =^ operator or, in its negated form, the !^ operator is used:

$ marc21 filter -s '400/1#.a =^ "Love"' DUMP.mrc.gz -o out.mrc.gz
$ marc21 filter -s '400/1#.a =^ ["Hate", "Love"]' DUMP.mrc.gz -o out.mrc.gz
$ marc21 filter -s '400/1#{ [ac] =^ "Count" }' DUMP.mrc.gz -o out.mrc.gz

In contrast, the =$ operator can be used to check whether a subfield value ends with a specific suffix. Keep in mind that the $ character often has a special meaning on the command line and may need to be escaped.

$ marc21 filter -s '548.4 =$ "/gnd#dateOfBirthAndDeath"' DUMP.mrc.gz -o out.mrc.gz
$ marc21 filter -s '401/1#.a !$ "Ada"' DUMP.mrc.gz -o out.mrc.gz

Similarity comparisons between character strings are performed using the =* operator (in negated form !*). The normalized Levenshtein distance is calculated between the subfield value and the comparison value. If this is greater than the specified threshold value, the comparison is considered a match. The default threshold value is 0.8 and can be changed using the command line option --strsim-threshold:

$ marc21 filter -s --strsim-threshold 0.9 '100/1#.a =* "Lovelace, Bda"' \
    DUMP.mrc.gz -o out.mrc.gz

Transforming records into CSV/TSV format

In the fields of data science and data engineering, it is essential that data be organized in a rectangular table schema (similar to a relational database). If the data to be analyzed is available in this format, efficient tools such as Polars can be used to perform data analysis on the underlying data. Using the select command, records can be efficiently transformed into a tabular format. By default, the output is written in CSV format.

The following example demonstrates how to create a table in CSV format, where the first column (cn) contains the control number of the record, the second column (label) contains the name of the authority record, and the third column (gndsys) contains the GND classification. Since multiple notations from the GND classification can be assigned to a single authority record, the output generates multiple rows for these records.

$ marc21 select -ps --header 'cn,label,gndsys' \
    '001, 150.a, 065{ a | 2 == "sswd" }' DUMP.mrc.gz -o out.csv
207,505 records, 0 invalid | 102,139 records/s, elapsed: 00:00:01  

$ cat out.csv
cn,label,gndsys
040000028,A 302 D,31.9b
040000230,Aargauer,17.1
040000303,Abakus,28
040000443,Abbildung,28
040000540,ABC-Schutz,7.15a
040000540,ABC-Schutz,8.4
040000567,ABC-Waffen,8.4
040000656,Abdichtung,31.3b
040000656,Abdichtung,31.6
...

Summary Statistics

The frequency command (alias freq) is used to calculate frequency tables based on the values (columns) of a query expression. The output is in CSV/TSV format and sorted in descending order.

The following example generates a frequency table of the combinations gndgen and gndspec (subfield 2) found in subfield b of field 065:

$ marc21 frequency -ps -H 'gndgen,gendspec,count' \
    '065{ b | 2 == "gndgen" }, 065{ b | 2 == "gndspec" }' GND.mrc.gz \
    -o out.csv.gz
10,220,897 records, 0 invalid | 495,993 records/s, elapsed: 00:00:20

$ zcat out.csv.gz | head -10
gndgen,gndspec,count
p,piz,6522289
b,kiz,910734
f,vie,807018
b,,375426
u,wim,330810
u,wit,242153
g,gik,180608
s,saz,129500
b,kio,115566

Counting Records

The number of records contained in the input can be determined using the count command:

$ marc21 count GND.mrc.gz
10329438

The --where option can be used to count only those records that match a certain criterion:

$ marc21 count GND.mrc.gz --where 'ldr.type == "z" && 075{ b == "gik" && 2 == "gndspec" }'
179672

The print command output records in a human-readable format. The leader, control and data fields are written on a separate line. Consecutive records are divided by a blank line. The output of the command can be used in combination with standard UNIX tools such as grep, cut or sed. In the following example, a single data record is printed on the console:

$ marc21 print tests/data/ada.mrc --where '100/*.a =? "Love"'
LDR 03612nz  a2200589nc 4500
001 119232022
003 DE-101
005 20250720173911.0
008 950316n||azznnaabn           | aaa    |c
024/7# $a 119232022 $0 http://d-nb.info/gnd/119232022 $2 gnd
035 $a (DE-101)119232022
035 $a (DE-588)119232022
035 $z (DE-588)172642531
035 $z (DE-588a)172642531 $9 v:zg
035 $z (DE-588a)119232022 $9 v:zg
035 $z (DE-588c)4370325-2 $9 v:zg
040 $a DE-386 $c DE-386 $9 r:DE-576 $b ger $d 1841
042 $a gnd1
043 $c XA-GB
065 $a 28p $2 sswd
065 $a 9.5p $2 sswd
075 $b p $2 gndgen
075 $b piz $2 gndspec
079 $a g $q f $q s $q z $u w $u k $u v
100/1# $a Lovelace, Ada $d 1815-1852
375 $a 2 $2 iso5218
400/1# $a Lovelace, Augusta Ada ˜ofœ $d 1815-1852
400/1# $a Lovelace, Ada Augusta ˜ofœ $d 1815-1852
400/1# $a Byron, Ada $d 1815-1852
400/1# $a Byron King, Augusta Ada $d 1815-1852
400/1# $a King, Augusta Ada $d 1815-1852
400/1# $a King, Ada $d 1815-1852
400/1# $a King-Noel, Augusta Ada $c Countess of Lovelace $d 1815-1852
...

Partitioning

The input can be split into different subsets based on the values of a field or subfield using the partition command. For example, the following command partitions the authority records based on the GND classifications (field 065):

$ marc21 partition -ps '065{ a | 2 == "sswd" }' \
    authorities-gnd-sachbegriff_dnbmarc.mrc.gz -o out
207,505 records, 0 invalid | 100,033 records/s, elapsed: 00:00:01

$ tree out
out
├── 00.mrc
├── 10.10.mrc
├── 10.11a.mrc
├── 10.11b.mrc
├── 10.11c.mrc
...
├── 9.5b.mrc
├── 9.5c.mrc
└── 9.5p.mrc

1 directory, 346 files

Since the path expression for a record can produce multiple values, the partitions are generally not disjoint. If a value occurs multiple times for a record, the record is written to the respective partition only once.

Concepts

Tag Matcher

In MARC21, variable fields are uniquely identified by tags. A tag matcher is an expression used to filter those fields that match a specific tag.

In its simplest form, only the three numerical digits of a tag are specified. A match with a tag only exists if these digits exactly match those of the tag:

$ marc21 count tests/data/ada.mrc --where '001 == "119232022"'
1

$ marc21 count tests/data/ada.mrc --where '002 == "xyz"'
0

In order to identify more than one field, a pattern-based comparison must be performed. Each numerical digit of a tag can be specified by one of the following variants.

First, a digit can be represented by the wildcard character . that accepts all possible values from 0 to 9. For example, the following tag matcher accepts all fields that contains at least one field that begins with 0 and ends with 8. The middle position can contain any digit.

$ marc21 count tests/data/ada.mrc --where '0.8?'
1

Furthermore, a digit can also be represented by specifying a class of possible digits. In the following example, all fields that start with a zero, have either a two, three, or five in the second position, and end with a 5 are accepted.

$ marc21 count tests/data/ada.mrc --where '0[235]5?'
1

Similar to the character classes of a regular expression, several consecutive digits within a class can be combined into a range. The range is inclusive, and the upper interval limit must be greater than the lower limit. Note that a class can consist of more than one range expression.

$ marc21 count tests/data/ada.mrc --where '0[2-5]5?'
1

A class can also be specified in negated form (^). In this case, the matcher checks that the digit in the corresponding position of the tag does not originate from the class digits:

$ marc21 count tests/data/ada.mrc --where '04[^0-3]?'
0

After all, every options can be used in all positions of a tag matcher. In the most extreme case, the expressions ... and [0-9][0-9][0-9] accept every field, while the expression [^0-9][^0-9][^0-9] accepts no fields. In the following example, all fields that begin with any digit not followed by a 0and end with a 1, 2, 3, 5, or 6 are taken into account.

$ marc21 count tests/data/ada.mrc --where '.[^0][1-356].2 == "sswd"'
1

Indicator Matcher

Data fields are distinguished not only by the tag, but also by an indicator consisting of two lowercase ASCII alphabetic, numeric, or blank characters. The indicator matcher checks whether a data field matches the specified value. It always appears in combination with a tag matcher and is preceded by the prefix /.

The indicator matcher distinguishes between three types:

Note

If no indicator matcher is specified, only the fields that contain a space in both positions are taken into account.

Explicit Matching

The simplest form is to explicitly specify the two indicator positions, preceded by the prefix /. A space is not a valid value and must be replaced with #.

Examples

$ marc21 count tests/data/ada.mrc --where '400/1#?'
1

$ marc21 count tests/data/ada.mrc --where '400/11?'
0

Pattern Based Matching

If you need to specify more than one specific value for an indicator, the pattern-based approach can be helpful. In this case, a position can be either an explicit value, a class of values ([1-3]), or any value (.). The elements of a class are specified by listing the allowed values enclosed in square brackets (e.g., [136]). A class can also contain one or more ranges, such as [13-56-9]. Negation is also supported by prefixing the class with ^ ([^234]); this class matches all positions that are not 2, 3, or 4.

Examples

  • /2. — Indicators that begin with 2, followed by any value (e.g., 25 or 2#)
  • /2[35] — Indicators that begin with 2, followed by a 3 or 5 (22 or 25)
  • /2[3-5] — Indicators that begin with 2, followed by a 3, 4, or 5 (23, 24, or 25)
  • /2[^35] — Indicators that begin with 2 and are not followed by a 3 or 5 (e.g., 21, 2#, 29)
  • /[12][1#] — Indicators that begin with 1 or 2, followed by 1 or a blank (#) (e.g., 11, 12, 1#)
  • /.. or /[0-9#][0-9#] — Accepts all indicators
$ marc21 count tests/data/minna.mrc --where '083/0.?'
1

$ marc21 count tests/data/minna.mrc --where '083/0[34]?'
1

$ marc21 count tests/data/minna.mrc --where '083/0[3-5]?'
1

$ marc21 count tests/data/minna.mrc --where '083/0[^5-9#]?'
1

$ marc21 count tests/data/minna.mrc --where '083/[30][34]?'
1

$ marc21 count tests/data/minna.mrc --where '100/[0-9#][0-9#]?'
1

$ marc21 count tests/data/minna.mrc --where '083/..?'
1

Wildcard Matching

If you want to accept all possible indicators associated with a data field, you could use the wildcard expression /*:

$ marc21 count tests/data/ada.mrc --where '100/*.a =? "Ada"'
1

Subfield Matcher

A subfield matcher is an expression that is applied to a list of subfields (of a data field) and checks whether that list meets the specified criteria. The matcher is primarily used as part of a field matcher and as a constraint in query or path expressions.

The following elementary variants are distinguished:

  • The exists matcher ? checks whether a specific subfield is present
  • The count matcher # checks the number of occurrences a subfield
  • The comparison matcher compares the value of a subfield against a reference value
  • The contains matcher =? checks whether a subfield contains a specific phrase
  • The in matcher in checks whether the value of a subfield comes from a reference list
  • The starts-with matcher =^ checks whether the value of a subfield begins with a prefix
  • The ends-with matcher =$ checks whether the value of a subfield ends with a suffix
  • The similarity matcher =* checks whether the value of a subfield is similar to a reference value
  • The regex matcher =~ checks whether the value of a subfield matches a regular expression

Exists Matcher

The ? operator is used to check whether a data field has one or more subfields. The specific value of the subfield is irrelevant in this context. In the following example, the field 079 is checked to see if a subfield named u exists:

$ marc21 count tests/data/ada.mrc --where '079.a?'
1

By negating the expression, you can check whether a field does not contain a specific subfield:

$ marc21 count tests/data/ada.mrc --where '079{ !u? }'
0

$ marc21 count tests/data/ada.mrc --where '!079.x?'
1

By specifying a code class, you can check whether one of the specified subfields is present. The following example checks whether the field 079 contains either the subfield p or q:

$ marc21 count tests/data/ada.mrc --where '079{ [pq]? }'
1

$ marc21 count tests/data/ada.mrc --where '079.[pq]?'
1

Count Matcher

The count matcher (#) counts the number of occurrences of one or more subfields and compares that number against a reference value. The available comparison operators are ==, !=, >=, >, <=, and <. The count matcher can only be used in the long form of a field matcher.

$ marc21 count tests/data/ada.mrc --where '079{ #u > 2 }'
1

$ marc21 count tests/data/ada.mrc --where '079{ #[aq-w] >= 7 }'
1

Comparison Matcher

The comparison matcher compares the value of a subfield to a reference value. The available comparison operators are ==, !=, >=, >, <=, and <.

$ marc21 count tests/data/ada.mrc --where '075{ b == "piz" }'
1

$ marc21 count tests/data/ada.mrc --where '075.b != "piz"'
1

Optionally, the statement can be quantified using the universal quantifier ALL or the existential quantifier ANY. By default, the existential quantifier is used; that is, the existence of at least one subfield that corresponds to the reference value according to the operator is sufficient for the statement to be true. Quantified expressions can’t be used in the short form of a field matcher.

$ marc21 count tests/data/ada.mrc --where '079{ ALL u >= "k" }'
1

$ marc21 count tests/data/ada.mrc --where '079{ ANY u != "k" }'
1

Contains Matcher

The contains matcher checks whether the specified substring is contained in the specified subfield. Internally, the matcher uses the Aho–Corasick algorithm (with SIMD acceleration in some cases) to enable efficient substring searches.

$ marc21 count tests/data/ada.mrc --where '400/1#{ a =? "Augusta" }'
1

$ marc21 count tests/data/ada.mrc --where '400/1#.a =? "Augusta"'
1

The matcher also allows you to search for multiple substrings at once by specifying a list of substrings:

$ marc21 count tests/data/ada.mrc --where '400/1#.a =? ["Hate", "Love"]'
1

To check whether a substring (or a list of substrings) is not contained, use the !? operator:

$ marc21 count tests/data/ada.mrc --where '400/1#.a !? "Curie"'
1

Finally, the statements can be quantified using the universal quantifier ALL or the existential quantifier ANY. A quantifier can’t be used in the short form of a field matcher.

$ marc21 count tests/data/ada.mrc --where '035{ ALL [az] =? "DE-" }'
1

In Matcher

The in matcher checks whether the value of a subfield comes from a reference list. The values are specified as a non-empty, comma-separated list enclosed in square brackets. If you want to check whether the value of a field does not come from a list, use the not in operator instead of in.

$ marc21 count tests/data/ada.mrc --where '075{ b in ["p", "s", "u"] }'
1

$ marc21 count tests/data/ada.mrc --where '075.b in ["p", "s", "u"]'
1

$ marc21 count tests/data/ada.mrc --where '075.b not in ["b", "f", "g"]'
1

The statements can be quantified using the universal quantifier ALL or the existential quantifier ANY. A quantifier can’t be used in the short form of a field matcher.

$ marc21 count tests/data/ada.mrc --where '079{ ALL u in ["w", "k", "v"] }'
1

Starts-With Matcher

The starts-with matcher checks whether the value of a subfield begins with a prefix. If the matcher is to search for multiple possible prefixes, the values are specified as a list. To check whether the value does not begin with a prefix, the !^ operator is used.

$ marc21 count tests/data/ada.mrc --where '400/1#{ a =^ "Love" }'
1

$ marc21 count tests/data/ada.mrc --where '400/1#.a =^ "Lovelace"'
1

$ marc21 count tests/data/ada.mrc --where '400/1#.a =^ ["Love", "Hate"]'
1

$ marc21 count tests/data/ada.mrc --where '400/1#.a !^ "Hate"'
1

The statements can be quantified using the universal quantifier ALL or the existential quantifier ANY. A quantifier can’t be used in the short form of a field matcher.

$ marc21 count tests/data/ada.mrc --where '400/1#{ ALL d =^ "1815" }'
1

Ends-With Matcher

The ends-with matcher checks whether the value of a subfield ends with a suffix. If the matcher is to search for multiple possible suffixes, the values are specified as a list. To check whether the value does not end with a suffix, the !$ operator is used.

$ marc21 count tests/data/ada.mrc --where '400/1#{ a =$ "Ada" }'
1

$ marc21 count tests/data/ada.mrc --where '400/1#.a =$ "Ada"'
1

$ marc21 count tests/data/ada.mrc --where '400/1#.a =$ ["Ada", "Bob"]'
1

$ marc21 count tests/data/ada.mrc --where '400/1#.a !$ "Ada"'
1

The statements can be quantified using the universal quantifier ALL or the existential quantifier ANY. A quantifier can’t be used in the short form of a field matcher.

$ marc21 count tests/data/ada.mrc --where '400/1#{ ALL d =$ "1852" }'
1

Similarity Matcher

The similarity matcher checks whether the value of a subfield is similar to a reference value. Similarity is determined by calculating the normalized Levenshtein distance between the subfield value and the reference value. The values range from 0.0 to 1.0 (inclusive), where a value of 1.0 indicates that the two values match. A match is considered to exist if the similarity value is greater than or equal to the threshold value, which can be configured using the command-line option --strsim-threshold and defaults to 80 (≙ 0.8). To check for non-similarity, the !* operator is used.

$ marc21 count tests/data/ada.mrc --where '400/1#{ a =* "Kong, Ada" }'
1

$ marc21 count tests/data/ada.mrc --where '400/1#{ a =* "Hatless, Ada" }'
0

$ marc21 count tests/data/ada.mrc --where '400/1#{ a !* "Hatless, Ada" }'
1

The statements can be quantified using the universal quantifier ALL or the existential quantifier ANY. A quantifier can’t be used in the short form of a field matcher.

Regex Matcher

The regex matcher =~ checks whether the value of a subfield matches a regular expression. To check multiple patterns at once, list all patterns in square brackets. To check whether the value does not match a regular expression, use the !~ operator.

Note

Not all regex functions are supported. Please consult the syntax documentation of the regex library used in this project if you have any questions.

Also keep in mind that, depending on the context and the type of quotes used (single or double), special characters in the regular expression may need to be quoted.

$ marc21 count tests/data/ada.mrc --where '400/1#{ d =~ "^\\d{4}-\\d{4}$" }'
1

$ marc21 count tests/data/ada.mrc --where '075.b =~ ["^[bfg]$", "^piz$"]'
1

$ marc21 count tests/data/ada.mrc --where '400/1#.d =~ "^\\d{4}-\\d{4}$"'
1

$ marc21 count tests/data/ada.mrc --where 'ALL 075.2 =~ "^gnd(gen|spec)$"'
1

$ marc21 count tests/data/ada.mrc --where '075.b !~ "^[bfg]$"'
1

The statements can be quantified using the universal quantifier ALL or the existential quantifier ANY. A quantifier can’t be used in the short form of a field matcher.

$ marc21 count tests/data/ada.mrc --where '079{ ALL u =~ "^[a-z]$" }'
1

Tip

The Rustexp website offers a regular expression editor and tester.

Record Matcher

The record matcher is the most important component of both the command-line tool marc21 and the Python extension polars-marc21. It allows for the efficient filtering of records (or their components) based on various criteria. A record matcher consists of either a leader matcher or a field matcher, which can be combined into more complex statements through Boolean connectives or grouping.

Leader Matcher

The leader matcher allows you to check the elements of the leader. The following fields can be checked:

  • base_addr — Base address of data (position 12-16)
  • encoding — Character coding scheme (position 09)
  • length — Record length (position 00-04)
  • status — Record status (position 05)
  • type — Type of record (position 06)

A leader matcher expression always consists of the prefix ldr. followed by the field to which the matcher refers. This is followed by a comparison operator (==, !=, >=, <=, >, or <), which specifies the type of comparison, and a reference value against the comparison is to be made. The data type of the reference value must match the data type of the corresponding leader field; i.e., the base address and record length can only be compared with a 32-bit unsigned integer value, and the remaining fields can only be compared with a single character enclosed in either single or double quotes.

Examples

Suppose we have the following leader field:

$ marc21 print tests/data/ada.mrc | egrep '^LDR'
LDR 03612nz  a2200589nc 4500

We can test this matcher using the count command in combination with the --where option. If the command returns the value 1, the leader of this record meets the criterion; otherwise, it does not.

$ marc21 count tests/data/ada.mrc --where 'ldr.base_addr > 500'
1

$ marc21 count tests/data/ada.mrc --where 'ldr.encoding != "a"'
0

$ marc21 count tests/data/ada.mrc --where 'ldr.length == 3612'
1

$ marc21 count tests/data/ada.mrc --where "ldr.status == 'n'"
1

$ marc21 count tests/data/ada.mrc --where 'ldr.type != "z"'
0

Field Matcher

The field matcher allows you to define criteria that must apply to variable fields. There are four different types: The control field matcher operates on control fields, the data field matcher on data fields, the exists matcher checks whether a field exists, and the count matcher checks whether a specific number of fields are present.

Control Field Matcher

A control field matcher consists of four components:

  • a tag matcher to select the fields
  • an optional range to check only substrings
  • an comparison operator (==, !=, >=, >, <=, <) or in-operator,
  • a value (comparison operator) or a list of values (in-operator)

In the simplest case, control fields are compared by addressing the fields using a tag matcher, applying a comparison operator, and specifying a comparison value.

$ marc21 count tests/data/ada.mrc --where '001 == "119232022"'
1

$ marc21 count tests/data/ada.mrc --where '003 != "DE-101"'
0

Some control fields contain fixed-length data elements. To access individual elements, you can optionally specify a range that defines the start (inclusive) and end (exclusive). If the value of the field contains this substring, it is compared to the reference value using the specified operator.

In the following example, all authority records are filtered where the date of last transaction (field 005, first 8 characters) is earlier than January 1, 2025:

$ marc21 count tests/data/ada.mrc --where '001[0:8] < "20260101"'
1

$ marc21 count tests/data/ada.mrc --where '001[:8] < "20260101"'
1

Note that, if the start value is omitted (e.g., 004[:4]), the start is set to 0. If the end value is omitted (e.g., 003[3:]), the end is automatically set to the length of the corresponding value.

The in operator can be used to check whether the value of a control field comes from a reference list, or not (not in):

$ marc21 count tests/data/ada.mrc --where '003 in ["DE-101", "DE-1979"]'
1

$ marc21 count tests/data/ada.mrc --where '005[:4] not in ["2023", "2024"]'
1

Data Field Matcher

tba

Exists Matcher

tba

Count Matcher

tba

Boolean Connectives

tba

Grouping

tba

Query

tba

Path

tba

Reference

Commands

The marc21 tool provides the following commands:

  • concat — Concatenate records from multiple inputs (alias cat)
  • count — Print the number of records in the input data (alias cnt)
  • filter — Filter records that fulfill a specified condition
  • hash — Compute SHA-256 checksum of records
  • invalid — Output invalid records that cannot be decoded
  • print — Print records in human readable format
  • sample — Select a random permutation of records
  • split — Split the input into chunks of a given size

marc21-concat(1)

NAME

marc21-concat — Concatenate records from multiple inputs

SYNOPSIS

marc21 concat [options] [path]…
marc21 cat [options] [path]…

DESCRIPTION

The concat command is used to combine records from multiple files into a single file or output (stdout).

OPTIONS

-a, --append
Append to the given file, do not overwrite. This option is not supported when writing to Gzip compressed output. When writing to stdout this flag is ignored.
--tee <path>
Write to the output and the file <path> at the same time. This option can be particularly useful when the output is written to stdout for further processing in a pipeline, but the output is also needed for following processing step.

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

In the following example, the five files dnb_all_dnbmarc.1.mrc.gz to dnb_all_dnbmarc.5.mrc.gz are concatenated into a single file DNB.mrc.gz. Invalid data records are skipped (option -s):

$ marc21 concat -s dnb_all_dnbmarc.*.mrc.gz -o DNB.mrc.gz

marc21-count(1)

NAME

marc21-count — Print the number of records in the indput data.

SYNOPSIS

marc21 count [options] [path]…
marc21 cnt [options] [path]…

DESCRIPTION

The count is used to determine the number of records contained in the input.

OPTIONS

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

tba

marc21-dedup(1)

NAME

marc21-dedup — Remove duplicate records from the input

SYNOPSIS

marc21 count [OPTIONS] [PATH]…

DESCRIPTION

This command deduplicates records that occur multiple times. Duplicates are identified by comparing the control number (field 001) of a record.

OPTIONS

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

In the following example, all duplicate records found in the input files s1.mrc and s2.mrc are removed and written to the output file out.mrc:

$ marc21 dedup s1.mrc s2.mrc -o out.mrc

marc21-describe(1)

NAME

marc21-describe — Creates a frequency table of all subfield codes

SYNOPSIS

marc21 describe [OPTIONS] [PATH]…

DESCRIPTION

The describe command creates a table that lists, for each field, how often a subfield code appears in the input. Since subfields appear only in the data fields, control fields are not included in the output. The columns ind1 and ind2 contain the values of the indicators.

OPTIONS

--tsv
Write output tab-separated (TSV)
-o, --output <path>
Write output to <path> instead of stdout. If the filename ends in .tsv or .tsv.gz, the output is automatically saved in TSV format. The output is gzip-compressed when the filename ends with .gz.

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

$ marc21 describe -s GND.mrc -o out.csv
10,220,897 records, 0 invalid | 472,874 records/s, elapsed: 00:00:21

$ head -10 out.csv
field,ind1,ind2,0,2,3,4,5,9,S,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,z
024,7, ,10220897,10863183,0,0,0,198362,0,10863183,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
034, , ,132557,135686,50,0,0,136105,0,0,0,0,136068,136068,136068,136068,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
035, , ,0,0,0,0,0,5495629,0,20441794,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6637796
040, , ,0,0,0,0,0,10220996,0,10220901,10220897,10220901,10220897,4524432,260659,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
042, , ,0,0,0,0,0,0,0,10220897,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
043, , ,0,0,0,0,0,15,0,0,0,9157636,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
065, , ,0,2617204,0,0,0,0,0,2617204,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
075, , ,0,20051640,0,0,0,0,0,0,20080983,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
079, , ,0,0,0,0,0,0,0,10220897,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12469759,0,0,0,5126056,0,0,0,0

marc21-filter(1)

NAME

marc21-filter — Filter records that fulfill a specified condition

SYNOPSIS

marc21 filter [options] [path]…

DESCRIPTION

tba

OPTIONS

-v, --invert_match
Inverts the specified filter criterion, which means that only records that do not match the criterion are returned.
--filter-normalization <form>
Transliterate the given filter expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

tba

marc21-frequency(1)

NAME

marc21-frequency — Compute a frequency table of values

SYNOPSIS

marc21 frequency [OPTIONS] <QUERY> [PATH]…
marc21 freq [OPTIONS] <QUERY> [PATH]…

DESCRIPTION

This command computes a frequency table over all values (columns) of the given query expression. The resulting frequency table is sorted in descending order (the most frequent value is printed first). If the count of two or more subfield values is equal, these lines are given in lexicographical order. The set of data fields, which are included in the result of a record, can be restricted by an optional predicate.

ARGUMENTS

<QUERY>
A MARC-21 query expression.

OPTIONS

-u, --unique
This flag ensures that all values generated for a record are counted only once in the frequency table.
-r, --reverse
Sort results in reverse order
-t <n>, --threshold <n>
Ignore rows with a frequency less than <n>.
-n <n>, --num <n>
Limit result to the <n> most frequent subfield values. The value 0 means no restriction.
-H, --header <header>
Insert a header row before the data. The header should be entered as a comma-separated list. Leading and trailing spaces in each column are automatically removed.
--tsv
Write output tab-separated (TSV)
-o, --output <path>
Write output to <path> instead of stdout. If the filename ends in .tsv or .tsv.gz, the output is automatically saved in TSV format. The output is gzip-compressed when the filename ends with .gz.

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

The following example creates a frequency table based on the year of the last update (field 005/00-04).

$ marc21 frequency -s -H 'year,count' '005[0:4]' GND.mrc`
year,count
2025,1193157
2024,1131644
2021,854178
2022,848635
2023,760070
2016,734399
2010,564136
2017,522303
2020,498302
2008,465916
2019,423590
2011,423077
2014,422959
2018,375568
2013,295991
2015,245866
2026,221200
2012,135738
2009,104168

marc21-glimpse(1)

NAME

marc21-glimpse — Print a dense preview of a data field

SYNOPSIS

marc21 glimpse [OPTIONS] <PATH> [INPUT]…

DESCRIPTION

This command generates a dense preview of the subfields of a data field (control fields and the leader are not processed). The preview is generated by progressively analyzing the relevant data fields from records until a minimum number of values has been found for each subfield encountered. The minimum number can be specified using the --max-values / -n option (the default value is 10).

Please note that subfields that appear very late in the input may not be listed in the preview. To get an overview of the distribution of the subfields, use the describe command.

It is also important to note that there does not have to be any relationship between the values in the same column. The values might come from different fields or records.

ARGUMENTS

<PATH>
A path expression.

OPTIONS

-n <n>, --max-values <n>
Maximum number of values to show per subfield (default 10).
-o, --output <path>
Write output to <path> instead of stdout. If the filename ends in .tsv or .tsv.gz, the output is automatically saved in TSV format. The output is gzip-compressed when the filename ends with .gz.

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

In the following example, a preview of field 065 is generated provided that subfield 2 contains the value sswd.

$ marc21 glimpse -n5 '065{ _ | 2 == "sswd" }' DUMP.mrc.gz
$2 sswd, sswd, sswd, sswd, sswd
$a 12.2p, 16.5p, 15.1p, 13.4p, 7.14p

The _ character indicates that the path expression does not impose any restrictions on the subfield codes. If only a subset of the subfields is to be considered, these can also be specified explicitly:

$ marc21 glimpse -s -n10 '079.[aq]' DUMP.mrc.gz
$a g, g, g, g, g, g, g
$q s, a, f, z, h, l, d, a, f, s

marc21-grep(1)

NAME

marc21-grep — Search for records whose values match a pattern

SYNOPSIS

marc21 grep [OPTIONS] <PATTERN> [INPUT]…

DESCRIPTION

The grep command searches for records whose values match one or multiple patterns (regular expressions). Only values from control and data fields are searched.

ARGUMENTS

<PATTERN>
A regular expression used for searching.

OPTIONS

--or <pattern>
Search for multiple, possibly overlapping, regexes in a single search. The regular expression consists of the main pattern and all other pattern passed by this option. The regex matches if a subfield is found that matches against at least one pattern.
-i, --ignore-case
If this flag is set, matching will be performed case insensitive. This setting applies to all specified patterns. If you want to match only a single pattern in a case-insensitive mode, you can do so using the inline flag i. For example, (?i:foo) matches foo case insensitively while (?-i:foo) matches foo case sensitively.
-v, --invert-match
Inverts the specified regular expression, which means that only records that do not match the criterion are returned.
-o <filename>, --output <filename>
Write output to <filename> instead of stdout.

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

In the following example, all records that have a field with a value that matches the regular expression ^MARC[-\s]21$ are returned:

$ marc21 grep '^MARC[-\s]21$' GND.mrc.gz -o out.mrc

marc21-hash(1)

NAME

marc21-hash — Compute SHA-256 checksum of records

SYNOPSIS

marc21 hash [options] [path]…

DESCRIPTION

tba

OPTIONS

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

tba

marc21-invalid(1)

NAME

marc21-invalid — Output invalid records that cannot be decoded

SYNOPSIS

marc21 invalid [options] [path]…

DESCRIPTION

tba

OPTIONS

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

tba

marc21-partition(1)

NAME

marc21-partition — Partition records by values.

SYNOPSIS

marc21 partition [OPTIONS] [PATH]…

DESCRIPTION

The partitions are written to the <outdir> directory. The filename can be changed using the --template option. By default, the partitions are saved with the corresponding value and the .mrc file extension.

If a record doesn’t have the field/subfield, the record won’t be written to a partition. A record with multiple values will be written to each partition; thus the partitions may not be disjoint. In order to prevent duplicate records in a partition , all duplicate values of a record will be removed automatically.

ARGUMENTS

<PATH>
A MARC-21 Path expression.

OPTIONS

--template <string>
A template for naming the individual partitions. The placeholder {} is replaced by the value of the path expression. If the template ends with the suffix .gz, the partitions are compressed in Gzip format.
-o, --output <path>
Write output to <path>; by default all partitions are written to the current working directory.

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

In the following example, all authority records are partitioned based on the date of the last record transaction (field 005), using only the year (positions 0 through 3) as the values:

$ marc21 partition -ps '005[0:4]' authorities-gnd-sachbegriff_dnbmarc.mrc.gz -o out
207,505 records, 0 invalid | 111,473 records/s, elapsed: 00:00:01

$ tree out
out
├── 2009.mrc
├── 2010.mrc
├── 2011.mrc
├── 2012.mrc
├── 2013.mrc
├── 2014.mrc
├── 2015.mrc
├── 2016.mrc
├── 2017.mrc
├── 2018.mrc
├── 2019.mrc
├── 2020.mrc
├── 2021.mrc
├── 2022.mrc
├── 2023.mrc
├── 2024.mrc
├── 2025.mrc
└── 2026.mrc

1 directory, 18 files

marc21-print(1)

NAME

marc21-print — Print records in human readable format

SYNOPSIS

marc21 print [options] [path]…

DESCRIPTION

This command print records in human readable format.

OPTIONS

--translit <form>
Transliterate the output into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc.

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

The following command prints the record from the file ada.mrc to the console:

$ marc21 print tests/data/ada.mrc
LDR 03612nz  a2200589nc 4500
001 119232022
003 DE-101
005 20250720173911.0
008 950316n||azznnaabn           | aaa    |c
024/7# $a 119232022 $0 http://d-nb.info/gnd/119232022 $2 gnd
035 $a (DE-101)119232022
035 $a (DE-588)119232022
035 $z (DE-588)172642531
035 $z (DE-588a)172642531 $9 v:zg
...

marc21-sample(1)

NAME

marc21-sample — Select a random permutation of records

SYNOPSIS

marc21 sample [options] [path]…

DESCRIPTION

tba

OPTIONS

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

tba

marc21-select(1)

NAME

marc21-select — Transforms records into CSV or TSV format

SYNOPSIS

marc21 select [OPTIONS] <QUERY> [PATH]…\

DESCRIPTION

This command allows you to efficiently transform records into a rectangular table schema. By default, the output is in CSV format.

ARGUMENTS

<QUERY>
A MARC-21 query expression.

OPTIONS

-H, --header <header>
Insert a header row before the data. The header should be entered as a comma-separated list. Leading and trailing spaces in each column are automatically removed.
--tsv
Write output tab-separated (TSV)
-o, --output <path>
Write output to <path> instead of stdout. If the filename ends in .tsv or .tsv.gz, the output is automatically saved in TSV format. The output is gzip-compressed when the filename ends with .gz.

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

This example demonstrates how to create a table in CSV format, where the first column (cn) contains the control number of the record, the second column (label) contains the name of the authority record, and the third column (gndsys) contains the GND classification. Since multiple notations from the GND classification system can be assigned to a single data record, the output generates multiple rows for these data records.

$ marc21 select -ps --header 'cn,label,gndsys' \
    '001, 150.a, 065{ a | 2 == "sswd" }' DUMP.mrc.gz -o out.csv
207,505 records, 0 invalid | 102,139 records/s, elapsed: 00:00:01  

$ head -10 out.csv
cn,label,gndsys
040000028,A 302 D,31.9b
040000230,Aargauer,17.1
040000303,Abakus,28
040000443,Abbildung,28
040000540,ABC-Schutz,7.15a
040000540,ABC-Schutz,8.4
040000567,ABC-Waffen,8.4
040000656,Abdichtung,31.3b
040000656,Abdichtung,31.6

marc21-skosify(1)

NAME

marc21-skosify — Convert records to SKOS/RDF

SYNOPSIS

marc21 skosify [options] [path]…

DESCRIPTION

This command converts a set of arbitrary MARC21 records into a SKOS/RDF graph. The specifications for how the conversion should be performed are defined in a configuration file.

Note

If you’re interested in converting MARC21 to SKOS/RDF, you should also take a look at mc2skos as an alternative.

CONFIGURATION

Parameterization is performed using a configuration file in TOML format, which must be specified using the -c or --config option.

Scope

If only a subset of the input records is to be processed, a filter criterion can be specified using the scope option. Only records that meet this criterion are included in the SKOS graph.

Note

In addition to this option, the set of records to be processed can also be limited using the command-line option --where. If both methods are used, a record must meet both criteria.

In the following example, the scope is defined as follows: Only authority records (leader type z) with an authentication code gnd1 (field 042 $a) and an authority data code s in field 079 $q are processed.

scope = 'ldr.type == "z" && 042.a == "gnd1" && 079.q == "s"'

Concept URI

There are two ways to specify the URI of a concept: Either by directly specifying it using a path expression (only the first value of the expression is used). In the following example, the URI from the field 024/7# $0 is used if the subfield $2 in the same field contains the value gnd:

uri = { path = '024/7#{ 0 | 2 == "gnd" }' }

Alternatively, the URI can be created by concatenating a base URI and a value determined by a path expression (only the first value is used). In the following example, the URI is formed from the base URI https://d-nb.info and the control number of the record (field 001):

uri = { base-uri = 'https://d-nb.info/', path = '001' }

Groups

The properties of a concept are specified within a group. The group defines which SKOS property is derived from which MARC21 values. This type of specification takes into account the fact that the values are often located in other fields, depending on a property of the record. A group can therefore (optionally) be restricted to a subset of records by specifying a scope. The groups are processed in order. Processing of the groups stops when at least one triple has been generated for a record.

In the following example, a subject-heading group is created that refers only to GND subject headings (scope). The prefLabel (preferred) is derived from field 150 $a, and the altLabel (alternative) from field 450 $a. No hiddenLabels (hidden) are defined.

[group.subject-heading]
scope = '075{ b == "s" && 2 == "gndgen" }'
labels = [
  { kind = 'preferred', path = '150.a' },
  { kind = 'alternative', path = '450.a' },
]

Miscellaneous

pretty = true | false
The pretty flag can be used to specify whether extra effort should be made to format the output nicely. This flag should be used with caution, as grouping related triples can be very time- and resource-intensive. If the flag is not set (default), output occurs in streaming mode, meaning subject and predicate “factorization” will only occur based on the previous triple(s) in the stream.

OPTIONS

-c, --config
Specifies the configuration file that defines the parameters rules for the SKOS/RDF graph.
-o <filename>, --output <filename>
Write output to <filename> instead of stdout. The output is automatically Gzip-compressed if the file ends with the suffix .gz.

Filter Options

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

Common Options

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

In the following example, an SKOS graph is created that consists solely of GND entities of type saf (“Formangabe”). The literals for prefLabel and altLabel are taken from fields 150 $a and 450 $a.

scope = '''
  ldr.type == "z"
    && 075{ b == "saf" && b == "saz" && 2 == "gndspec" }
    && 042.a == "gnd1" && 079.q == "s"
'''

uri = {
  base-uri = "https://explore.gnd.network/gnd/",
  path = '001'
}

[group.entity-type-saf]
labels = [
  { kind = 'preferred', path = '150.a' },
  { kind = 'alternative', path = '450.a' },
]

The graph can be generated using the following command (for the sake of brevity, the output has been limited to the Rezension (review/recension) entity):

$ marc21 skosify -c saf.toml authorities-gnd-sachbegriff_dnbmarc.mrc.gz \
    --where '001 == "040497127"'
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
<https://explore.gnd.network/gnd/040497127> a <http://www.w3.org/2004/02/skos/core#Concept>;
        <http://www.w3.org/2004/02/skos/core#prefLabel> "Rezension";
        <http://www.w3.org/2004/02/skos/core#altLabel> "Buchbesprechung",
                "Buchrezension",
                "Buchkritik".

marc21-split(1)

NAME

marc21-split — Split the input into chunks of a given size

SYNOPSIS

marc21 split [options] [path]…

DESCRIPTION

tba

OPTIONS

FILTER OPTIONS

-l, --limit <n>
Limit the result to first <n> records (a limit value 0 means no limit)
-s, --skip-invalid
Skip invalid records that can’t be decoded
--strsim-threshold <value>
The minimum score for string similarity comparisons. The value must be between 0 and 100.
--where
An filter expression for filtering records
--filter-normalization <form>
Transliterate the given filter or query expression into the specified Unicode normal form. Possible values: nfd, nfkd, nfc, nfkc. This option can also be specified by setting the environment variable MARC21_FILTER_NORMALIZATION.

COMMON OPTIONS

-p, --progress
If set, show a progress bar
--compression
Specify compression level (0..=9)

EXIT STATUS

  • 0 — Command succeeded.
  • 1 — Command failed.

EXAMPLES

tba