mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Added string case operators
This commit is contained in:
parent
71706af3d4
commit
d7b158f855
@ -49,6 +49,38 @@ Note that versions prior to 4.18 require the 'eval/e' command to be specified.&#
|
||||
`yq e <exp> <file>`
|
||||
{% endhint %}
|
||||
|
||||
## To up (upper) case
|
||||
Works with unicode characters
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
água
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq 'upcase' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
ÁGUA
|
||||
```
|
||||
|
||||
## To down (lower) case
|
||||
Works with unicode characters
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
ÁgUA
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq 'downcase' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
água
|
||||
```
|
||||
|
||||
## Join strings
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
|
@ -414,6 +414,12 @@ func initLexer() (*lex.Lexer, error) {
|
||||
lexer.Add([]byte(`capture`), opToken(captureOpType))
|
||||
lexer.Add([]byte(`test`), opToken(testOpType))
|
||||
|
||||
lexer.Add([]byte(`upcase`), opTokenWithPrefs(changeCaseOpType, nil, changeCasePrefs{ToUpperCase: true}))
|
||||
lexer.Add([]byte(`ascii_upcase`), opTokenWithPrefs(changeCaseOpType, nil, changeCasePrefs{ToUpperCase: true}))
|
||||
|
||||
lexer.Add([]byte(`downcase`), opTokenWithPrefs(changeCaseOpType, nil, changeCasePrefs{ToUpperCase: false}))
|
||||
lexer.Add([]byte(`ascii_downcase`), opTokenWithPrefs(changeCaseOpType, nil, changeCasePrefs{ToUpperCase: false}))
|
||||
|
||||
lexer.Add([]byte(`sort`), opToken(sortOpType))
|
||||
lexer.Add([]byte(`sort_by`), opToken(sortByOpType))
|
||||
lexer.Add([]byte(`reverse`), opToken(reverseOpType))
|
||||
|
@ -125,13 +125,16 @@ var explodeOpType = &operationType{Type: "EXPLODE", NumArgs: 1, Precedence: 50,
|
||||
var sortByOpType = &operationType{Type: "SORT_BY", NumArgs: 1, Precedence: 50, Handler: sortByOperator}
|
||||
var reverseOpType = &operationType{Type: "REVERSE", NumArgs: 0, Precedence: 50, Handler: reverseOperator}
|
||||
var sortOpType = &operationType{Type: "SORT", NumArgs: 0, Precedence: 50, Handler: sortOperator}
|
||||
|
||||
var sortKeysOpType = &operationType{Type: "SORT_KEYS", NumArgs: 1, Precedence: 50, Handler: sortKeysOperator}
|
||||
|
||||
var joinStringOpType = &operationType{Type: "JOIN", NumArgs: 1, Precedence: 50, Handler: joinStringOperator}
|
||||
var subStringOpType = &operationType{Type: "SUBSTR", NumArgs: 1, Precedence: 50, Handler: substituteStringOperator}
|
||||
var matchOpType = &operationType{Type: "MATCH", NumArgs: 1, Precedence: 50, Handler: matchOperator}
|
||||
var captureOpType = &operationType{Type: "CAPTURE", NumArgs: 1, Precedence: 50, Handler: captureOperator}
|
||||
var testOpType = &operationType{Type: "TEST", NumArgs: 1, Precedence: 50, Handler: testOperator}
|
||||
var splitStringOpType = &operationType{Type: "SPLIT", NumArgs: 1, Precedence: 50, Handler: splitStringOperator}
|
||||
var changeCaseOpType = &operationType{Type: "CHANGE_CASE", NumArgs: 0, Precedence: 50, Handler: changeCaseOperator}
|
||||
|
||||
var loadOpType = &operationType{Type: "LOAD", NumArgs: 1, Precedence: 50, Handler: loadYamlOperator}
|
||||
|
||||
|
@ -9,6 +9,37 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type changeCasePrefs struct {
|
||||
ToUpperCase bool
|
||||
}
|
||||
|
||||
func changeCaseOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
||||
results := list.New()
|
||||
prefs := expressionNode.Operation.Preferences.(changeCasePrefs)
|
||||
|
||||
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
|
||||
node := unwrapDoc(candidate.Node)
|
||||
|
||||
if guessTagFromCustomType(node) != "!!str" {
|
||||
return Context{}, fmt.Errorf("cannot change case with %v, can only operate on strings. ", node.Tag)
|
||||
}
|
||||
|
||||
newStringNode := &yaml.Node{Kind: yaml.ScalarNode, Tag: node.Tag, Style: node.Style}
|
||||
if prefs.ToUpperCase {
|
||||
newStringNode.Value = strings.ToUpper(node.Value)
|
||||
} else {
|
||||
newStringNode.Value = strings.ToLower(node.Value)
|
||||
}
|
||||
results.PushBack(candidate.CreateReplacement(newStringNode))
|
||||
|
||||
}
|
||||
|
||||
return context.ChildContext(results), nil
|
||||
|
||||
}
|
||||
|
||||
func getSubstituteParameters(d *dataTreeNavigator, block *ExpressionNode, context Context) (string, string, error) {
|
||||
regEx := ""
|
||||
replacementText := ""
|
||||
|
@ -5,6 +5,40 @@ import (
|
||||
)
|
||||
|
||||
var stringsOperatorScenarios = []expressionScenario{
|
||||
{
|
||||
description: "To up (upper) case",
|
||||
subdescription: "Works with unicode characters",
|
||||
document: `água`,
|
||||
expression: "upcase",
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::ÁGUA\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
document: `!camel água`,
|
||||
expression: "upcase",
|
||||
expected: []string{
|
||||
"D0, P[], (!camel)::ÁGUA\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "To down (lower) case",
|
||||
subdescription: "Works with unicode characters",
|
||||
document: `ÁgUA`,
|
||||
expression: "downcase",
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::água\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
document: `!camel ÁgUA`,
|
||||
expression: "downcase",
|
||||
expected: []string{
|
||||
"D0, P[], (!camel)::água\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Join strings",
|
||||
document: `[cat, meow, 1, null, true]`,
|
||||
|
Loading…
Reference in New Issue
Block a user