gnu-recutils
Work with GNU recutils for plain-text record databases. Use when creating, querying, or validating .rec files, defining record schemas with %rec descriptors, converting between rec/CSV formats, or when the user mentions recutils, recsel, recins, recfmt, or record-oriented data files.
When & Why to Use This Skill
This Claude skill provides comprehensive support for GNU recutils, a specialized set of tools for managing human-readable, plain-text databases. It enables users to efficiently create, query, and validate .rec files, define structured schemas with advanced descriptors, and perform seamless data conversions between rec and CSV formats. By leveraging this skill, users can maintain version-controllable, record-oriented data systems without the overhead of traditional database engines.
Use Cases
- Scenario 1: Managing project metadata or configuration files in a human-readable format that is easily tracked by version control systems like Git.
- Scenario 2: Defining and enforcing strict data schemas for text-based records using %rec descriptors to ensure data integrity and type safety.
- Scenario 3: Performing complex data queries and filtering on plain-text files using recsel expressions for rapid data retrieval.
- Scenario 4: Converting legacy CSV datasets into structured .rec files to utilize advanced features like foreign key references and multi-line field values.
- Scenario 5: Automating the validation and sorting of record-oriented data files to maintain clean and organized data structures.
| name | gnu-recutils |
|---|---|
| description | Work with GNU recutils for plain-text record databases. Use when creating, querying, or validating .rec files, defining record schemas with %rec descriptors, converting between rec/CSV formats, or when the user mentions recutils, recsel, recins, recfmt, or record-oriented data files. |
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 |
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 --checkbefore 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 -pand 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.