Learn-skills.dev dasel

install
source · Clone the upstream repo
git clone https://github.com/NeverSight/learn-skills.dev
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/aaronflorey/agent-skills/dasel" ~/.claude/skills/neversight-learn-skills-dev-dasel && rm -rf "$T"
manifest: data/skills-md/aaronflorey/agent-skills/dasel/SKILL.md
source content

Dasel v3

Dasel (Data-Select) is a CLI tool for querying, modifying, and converting structured data files using a consistent query syntax across formats.

Docs are bundled in

references/
. Read them when you need deeper detail on a topic.


CLI basics

# Read from stdin, specify input format
echo '{"name":"Tom"}' | dasel -i json 'name'
# => "Tom"

# Read from a file via stdin redirection
dasel -i yaml 'database.host' < config.yaml

# Convert formats: read JSON, output YAML
cat data.json | dasel -i json -o yaml

# Output the whole document (needed when modifying)
echo '{"a":1}' | dasel -i json --root 'a = 2'
# => {"a": 2}

Key flags:

FlagShortPurpose
--in FORMAT
-i
Input format (json, yaml, toml, xml, csv, hcl, ini)
--out FORMAT
-o
Output format
--root
Output the full document, not just the selected value
--var name=fmt:file:path
Pass a file as a named variable
--read-flag key=val
Parser-specific read options
--write-flag key=val
Parser-specific write options
--config PATH
-c
Path to dasel config file (default:
~/dasel.yaml
)
--unstable
Enable unstable/experimental features

Query syntax

Queries are dot-chained accessors and function calls, terminated with

;
when using multiple statements.

# Access nested fields
user.address.city

# Array index (zero-based)
users[0].name

# Range slice
users[0:4]

# Assign (modifies the value in the document)
user.name = "Alice"

# Variables - $root is stdin, $this is current element
$root.users.filter(active == true).map(name)

Multi-statement queries (use

;
to separate, last statement is the output):

$active = $root.users.filter(active == true);
$active.map(name)

Environment variables

GREETING=hello NAME=tom dasel '$GREETING + " " + $NAME'
# => "hello tom"

Common patterns

Read a value

echo '{"foo":{"bar":"baz"}}' | dasel -i json 'foo.bar'
# => "baz"

Modify a value (output full document)

echo '{"foo":"old"}' | dasel -i json --root 'foo = "new"'
# => {"foo": "new"}

Edit a file in place

dasel -i yaml --root 'server.port = 9090' < config.yaml > config.yaml.tmp \
  && mv config.yaml.tmp config.yaml

Note: there is no

-f
flag for data files in v3. Always use stdin (
< file
or
cat file |
). Note: always go via a temp file — bash truncates the target before dasel reads it.

Filter an array

echo '{"users":[{"name":"Alice","active":true},{"name":"Bob","active":false}]}' \
  | dasel -i json 'users.filter(active == true).map(name)'
# => ["Alice"]

Map / transform

echo '[1,2,3]' | dasel -i json 'map($this * 2)'
# => [2, 4, 6]

Modify elements in place with
each

echo '[1,2,3]' | dasel -i json 'each($this = $this + 1)'
# => [2, 3, 4]

Default / coalesce

# Fall back to a default if path missing
dasel -f config.yaml 'server.timeout ?? 30'

Conditional

dasel -f data.json 'if(count > 5) { "many" } else { "few" }'

Recursive descent — find all values by key

# All values with key "name" at any depth
dasel -f data.json '..name'

# All values at any depth
dasel -f data.json '..*'

Predicate-based deep search

dasel -f data.json 'search(has("id") && has("name"))'

Format conversion

cat file.json | dasel -i json -o yaml
cat file.yaml | dasel -i yaml -o toml

Build a new object

echo '{"first":"Tom","last":"Wright"}' \
  | dasel -i json '{"fullName": first + " " + last}'

Spread operator

# Merge objects
echo '{"a":1}' | dasel -i json '{$this..., "b": 2}'
# => {"a":1,"b":2}

# Append to array
echo '[1,2,3]' | dasel -i json '[$this..., 4, 5]'
# => [1,2,3,4,5]

Supported formats

FormatReadWriteNotes
json
yaml
xmlSee
--read-flag xml-mode=structured
csvAll values as strings;
--read-flag csv-delimiter=;
hcl
--read-flag hcl-block-format=array
tomlGenerally working; unsorted maps
iniBasic sections + key values only

Key functions

FunctionDescriptionExample
filter(pred)
Filter array by predicate
arr.filter($this > 1)
map(expr)
Transform each element
arr.map($this * 2)
each(expr)
Iterate and modify in place
arr.each($this = $this+1)
search(pred)
Recursive predicate search
search(has("key"))
has(key)
Check key/index exists
has("name")
len(x)
Length of array/string
len($root.items)
keys(obj)
Keys of a map
keys($root.config)
add(a,b)
Add / concatenate
add(1, 2)
join(arr, sep)
Join array to string
join(tags, ",")
replace(str,old,new)
String replace
replace(name,"_"," ")
sortBy(key)
Sort array of objects
users.sortBy(name)
reverse(arr)
Reverse array
reverse(items)
min(arr)
/
max(arr)
Min/max of numbers
min(scores)
sum(arr)
Sum numbers
sum(prices)
toString(x)
Convert to string
toString(id)
toInt(x)
Convert to int
toInt(count)
typeOf(x)
Type name
typeOf(value)
parse(fmt, str)
Parse a string as a format
parse("json", raw)
readFile(path)
Read a file
readFile("x.json")
base64e(str)
Base64 encode
base64e(token)
base64d(str)
Base64 decode
base64d(encoded)

For full function signatures and examples, see

references/functions.md
.


Reference files

FileWhen to read
references/syntax.md
Deep dive: types, arrays, objects, conditionals, spread, coalesce, branches, regex, recursive descent
references/functions.md
All function signatures with examples
references/input-output.md
Stdin/stdout, file editing, variables, format flags

Tips

  • Always use
    --root
    when modifying data and wanting the full document back.
  • Use
    ;
    to write multi-statement queries for clarity.
  • $root
    is the stdin document;
    $this
    is the current element inside functions.
  • For in-place file edits, always redirect to a
    .tmp
    file first, then
    mv
    .
  • The ternary operator (
    ? :
    ) is not yet implemented — use
    if/else
    form instead.
  • branch
    is unstable — requires
    --unstable
    flag.