docs: add hints for common syntax edge cases

Add informational hints to operator documentation covering behaviors
  that may differ from user expectations, particularly for those
  familiar with jq:

  - slice-array: clarify that slicing only works on arrays, not strings
  - select: document behavior when piping select to a literal value
  - equals: note bash history expansion with != operator
  - create-collect-into-object: mention that shorthand {key} syntax
    is not supported
  - collect-into-array: explain difference between [.x | .[]] and [.x[]]
This commit is contained in:
Chris Hamant 2026-01-28 02:51:22 -05:00
parent 0dcba85400
commit 3c0fd6a3e9
No known key found for this signature in database
5 changed files with 89 additions and 0 deletions

View File

@ -2,6 +2,19 @@
This creates an array using the expression between the square brackets.
{% hint style="warning" %}
_Note_ the placement of `|` when collecting. These two forms behave differently:
```bash
# Pipe then splat - creates separate context
[.items | .[] | has("id")]
# Splat directly on path - more common pattern
[.items[] | has("id")]
```
{% endhint %}
## Collect empty
Running

View File

@ -2,6 +2,12 @@
This is used to construct objects (or maps). This can be used against existing yaml, or to create fresh yaml documents.
{% hint style="info" %}
_Note_ for jq users: yq does not support shorthand object construction like `{name, version}`. Use the explicit form `{"name": .name, "version": .version}` or `pick(["name", "version"])` instead.
{% endhint %}
## Collect empty object
Running
```bash

View File

@ -14,6 +14,26 @@ select(.a == .b)
The not equals `!=` operator returns `false` if the LHS is equal to the RHS.
{% hint style="info" %}
_Note_ that the `!=` operator contains `!` which can trigger bash history expansion in interactive shells:
```bash
# May fail with: bash: !": event not found
yq '.status != "healthy"' file.yaml
```
Workarounds:
```bash
# Use $'...' quoting
yq $'.status != "healthy"' file.yaml
# Or use | not instead of !=
yq '.status == "healthy" | not' file.yaml
```
{% endhint %}
## Related Operators
- comparison (`>=`, `<` etc) operators [here](https://mikefarah.gitbook.io/yq/operators/compare)

View File

@ -137,3 +137,37 @@ a:
horse: dog
```
## Piping select to a literal
{% hint style="warning" %}
_Note_ that piping `select()` to a literal value produces that literal for each match. When there are no matches, the literal is still produced once:
Given a sample.yml file of:
```yaml
a: 1
```
then
```bash
yq '(.a | select(. == 999) | "matched") // "default"' sample.yml
```
will output
```yaml
matched
```
Since `.a` is `1`, not `999`, you might expect `"default"` here.
The select does filter correctly when not followed by a literal:
```bash
yq '.a | select(. == 999)' sample.yml
```
will output nothing (empty).
**Workaround**: Return the matched value itself, or use `with()`:
```bash
yq '(.a | select(. == 1)) // "default"' sample.yml
```
{% endhint %}

View File

@ -4,6 +4,22 @@ The slice array operator takes an array as input and returns a subarray. Like th
You may leave out the first or second number, which will refer to the start or end of the array respectively.
{% hint style="warning" %}
_Note_ that slicing only works on arrays, not strings. Using slice syntax on a string (e.g., `.text | .[0:5]`) will return an empty result instead of a substring.
For string slicing, use split/join or regex:
```bash
# Split into array, slice, rejoin
yq '.text | split("") | .[0:5] | join("")'
# Or use regex substitution
yq '.text | sub("^(.{5}).*"; "${1}")'
```
{% endhint %}
## Slicing arrays
Given a sample.yml file of:
```yaml