GNU Recutils
GNU recutils is a set of tools for managing human-readable, plain-text databases. Records are stored in .rec files with a simple field: value syntax.
Quick Reference
Core Commands
Command Purpose
recsel
Select and query records
recins
Insert new records
recdel
Delete records
recset
Modify field values
recfix
Validate, check integrity, sort
recfmt
Format output with templates
recinf
Print information about rec files
rec2csv
Convert to CSV
csv2rec
Convert from CSV
Basic File Format
Comment line
Field_name: field value Another_field: another value
Field_name: second record Another_field: its value
Records are separated by blank lines. Field names are case-sensitive and conventionally capitalized.
Multi-line Values
Use + continuation for multi-line content:
Description: This is the first line
- and this continues on the second line
- and a third line too.
Or use backslash at end of line:
Description: This is a long value that
continues on the next line.
Schema Definitions (%rec Descriptors)
Place schema declarations before records:
%rec: Entity %key: Id %mandatory: Id Name %allowed: Id Name Prototype Description OnLook OnTouch %type: Prototype rec Entity %type: Count int %type: Active bool %unique: Name
Id: sword Name: Iron Sword Count: 1 Active: yes
Common Descriptors
Descriptor Purpose Example
%rec: Type
Names the record type %rec: Entity
%key: field
Primary key (unique, mandatory) %key: Id
%mandatory: f1 f2
Required fields %mandatory: Id Name
%allowed: f1 f2
Whitelist of valid fields %allowed: Id Name Desc
%prohibit: f1
Forbidden fields %prohibit: Password
%unique: field
Field must be unique %unique: Email
%type: field type
Field type constraint %type: Count int
%auto: field
Auto-generated field %auto: Created_at
%sort: field
Default sort order %sort: Name
Field Types
Type Description Example Values
int
Integer 42 , -7
real
Floating point 3.14 , -2.5
bool
Boolean yes , no , true , false , 1 , 0
line
Single line (no newlines) Hello world
date
ISO 8601 date 2024-01-15
Email address user@example.com
uuid
UUID 550e8400-e29b-41d4-a716-446655440000
rec Type
Foreign key reference References another record type
enum A B C
Enumeration One of the listed values
regexp /pattern/
Regex pattern Must match pattern
size N
Max size in bytes String length limit
range MIN MAX
Numeric range range 1 100
Foreign Key References
%rec: Room %key: Id
Id: tavern Name: The Rusty Tavern
%rec: Entity %key: Id %type: Room rec Room
Id: mug Name: Beer Mug Room: tavern
Entity Containment (MUDD)
Entities can be nested using a Container field:
%rec: Entity %key: Id %type: Prototype rec Entity %type: Container rec Entity
Id: table Name: Wooden Table Prototype: furniture
Id: lamp Name: Brass Lamp Prototype: object Container: table
The lamp is "on" the table. Recfix validates that Container references exist.
Common Operations
Query Records
All records
recsel data.rec
Filter by field value
recsel -e 'Name = "sword"' data.rec
Pattern matching
recsel -e 'Name ~ "Iron"' data.rec
Numeric comparison
recsel -e 'Count > 5' data.rec
Multiple conditions
recsel -e 'Type = "weapon" && Count > 0' data.rec
Select specific fields
recsel -p Id,Name data.rec
Count matching records
recsel -c -e 'Active = yes' data.rec
Select by record type
recsel -t Entity data.rec
Insert Records
Insert from stdin
echo -e "Id: axe\nName: Battle Axe" | recins data.rec
Insert with field values
recins -f Id -v sword -f Name -v "Iron Sword" data.rec
Modify Records
Update field value
recset -e 'Id = "sword"' -f Count -s 5 data.rec
Delete field from record
recset -e 'Id = "sword"' -f Obsolete -d data.rec
Delete Records
Delete matching records
recdel -e 'Count = 0' data.rec
Delete by record number
recdel -n 3 data.rec
Validate
Check file integrity
recfix data.rec
Check and report all errors
recfix --check data.rec
Convert Formats
To CSV
rec2csv data.rec > data.csv
From CSV
csv2rec data.csv > data.rec
Format Output
Custom output format
recsel data.rec | recfmt '{{Id}}: {{Name}}\n'
Template-based formatting (recfmt reads from stdin)
recsel data.rec | recfmt -f template.fmt
Expression Syntax
Used with -e flag in recsel, recdel, recset:
Operator Meaning Example
=
Equals Name = "sword"
!=
Not equals Type != "armor"
< , > , <= , >=
Numeric comparison Count > 5
~
Regex match Name ~ "^Iron"
&&
Logical AND Type = "weapon" && Rare = yes
`
`
!
Logical NOT ! (Count = 0)
#field
Field count (0 if absent) #Description
Tips
-
Use recfix --check before loading data to catch schema violations
-
Foreign keys (%type: Field rec OtherType ) validate references exist
-
Field names start with a letter and contain only [a-zA-Z0-9_] ; special fields start with %
-
Empty lines separate records; use + continuation for multi-line values
-
Comments start with # at the beginning of a line
-
For JSON output, pipe through recsel -p and parse with a script
MUDD Naming Convention
In this project, entity fields use PascalCase (e.g., DescriptionShort , OnAttack ). This avoids visual noise from underscores. See data/entities.rec for examples.