AgentSkillsCN

gnu-recutils

使用GNU recutils处理纯文本记录数据库。适用于创建、查询或验证.rec文件、用%rec描述符定义记录模式、在rec/CSV格式间转换,或当用户提及recutils、recsel、recins、recfmt或以记录为导向的数据文件时。

SKILL.md
--- frontmatter
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

CommandPurpose
recselSelect and query records
recinsInsert new records
recdelDelete records
recsetModify field values
recfixValidate, check integrity, sort
recfmtFormat output with templates
recinfPrint information about rec files
rec2csvConvert to CSV
csv2recConvert from CSV

Basic File Format

rec
# 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:

rec
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:

rec
Description: This is a long value that \
continues on the next line.

Schema Definitions (%rec Descriptors)

Place schema declarations before records:

rec
%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

DescriptorPurposeExample
%rec: TypeNames the record type%rec: Entity
%key: fieldPrimary key (unique, mandatory)%key: Id
%mandatory: f1 f2Required fields%mandatory: Id Name
%allowed: f1 f2Whitelist of valid fields%allowed: Id Name Desc
%prohibit: f1Forbidden fields%prohibit: Password
%unique: fieldField must be unique%unique: Email
%type: field typeField type constraint%type: Count int
%auto: fieldAuto-generated field%auto: Created_at
%sort: fieldDefault sort order%sort: Name

Field Types

TypeDescriptionExample Values
intInteger42, -7
realFloating point3.14, -2.5
boolBooleanyes, no, true, false, 1, 0
lineSingle line (no newlines)Hello world
dateISO 8601 date2024-01-15
emailEmail addressuser@example.com
uuidUUID550e8400-e29b-41d4-a716-446655440000
rec TypeForeign key referenceReferences another record type
enum A B CEnumerationOne of the listed values
regexp /pattern/Regex patternMust match pattern
size NMax size in bytesString length limit
range MIN MAXNumeric rangerange 1 100

Foreign Key References

rec
%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
%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

bash
# 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

bash
# 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

bash
# 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

bash
# Delete matching records
recdel -e 'Count = 0' data.rec

# Delete by record number
recdel -n 3 data.rec

Validate

bash
# Check file integrity
recfix data.rec

# Check and report all errors
recfix --check data.rec

Convert Formats

bash
# To CSV
rec2csv data.rec > data.csv

# From CSV
csv2rec data.csv > data.rec

Format Output

bash
# 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:

OperatorMeaningExample
=EqualsName = "sword"
!=Not equalsType != "armor"
<, >, <=, >=Numeric comparisonCount > 5
~Regex matchName ~ "^Iron"
&&Logical ANDType = "weapon" && Rare = yes
``
!Logical NOT! (Count = 0)
#fieldField 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.