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.
$ 설치
git clone https://github.com/frizzle-chan/mudd /tmp/mudd && cp -r /tmp/mudd/.claude/skills/gnu-recutils ~/.claude/skills/mudd// tip: Run this command in your terminal to install the skill
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.
Repository
