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>`
|
`yq e <exp> <file>`
|
||||||
{% endhint %}
|
{% 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
|
## Join strings
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -414,6 +414,12 @@ func initLexer() (*lex.Lexer, error) {
|
|||||||
lexer.Add([]byte(`capture`), opToken(captureOpType))
|
lexer.Add([]byte(`capture`), opToken(captureOpType))
|
||||||
lexer.Add([]byte(`test`), opToken(testOpType))
|
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`), opToken(sortOpType))
|
||||||
lexer.Add([]byte(`sort_by`), opToken(sortByOpType))
|
lexer.Add([]byte(`sort_by`), opToken(sortByOpType))
|
||||||
lexer.Add([]byte(`reverse`), opToken(reverseOpType))
|
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 sortByOpType = &operationType{Type: "SORT_BY", NumArgs: 1, Precedence: 50, Handler: sortByOperator}
|
||||||
var reverseOpType = &operationType{Type: "REVERSE", NumArgs: 0, Precedence: 50, Handler: reverseOperator}
|
var reverseOpType = &operationType{Type: "REVERSE", NumArgs: 0, Precedence: 50, Handler: reverseOperator}
|
||||||
var sortOpType = &operationType{Type: "SORT", NumArgs: 0, Precedence: 50, Handler: sortOperator}
|
var sortOpType = &operationType{Type: "SORT", NumArgs: 0, Precedence: 50, Handler: sortOperator}
|
||||||
|
|
||||||
var sortKeysOpType = &operationType{Type: "SORT_KEYS", NumArgs: 1, Precedence: 50, Handler: sortKeysOperator}
|
var sortKeysOpType = &operationType{Type: "SORT_KEYS", NumArgs: 1, Precedence: 50, Handler: sortKeysOperator}
|
||||||
|
|
||||||
var joinStringOpType = &operationType{Type: "JOIN", NumArgs: 1, Precedence: 50, Handler: joinStringOperator}
|
var joinStringOpType = &operationType{Type: "JOIN", NumArgs: 1, Precedence: 50, Handler: joinStringOperator}
|
||||||
var subStringOpType = &operationType{Type: "SUBSTR", NumArgs: 1, Precedence: 50, Handler: substituteStringOperator}
|
var subStringOpType = &operationType{Type: "SUBSTR", NumArgs: 1, Precedence: 50, Handler: substituteStringOperator}
|
||||||
var matchOpType = &operationType{Type: "MATCH", NumArgs: 1, Precedence: 50, Handler: matchOperator}
|
var matchOpType = &operationType{Type: "MATCH", NumArgs: 1, Precedence: 50, Handler: matchOperator}
|
||||||
var captureOpType = &operationType{Type: "CAPTURE", NumArgs: 1, Precedence: 50, Handler: captureOperator}
|
var captureOpType = &operationType{Type: "CAPTURE", NumArgs: 1, Precedence: 50, Handler: captureOperator}
|
||||||
var testOpType = &operationType{Type: "TEST", NumArgs: 1, Precedence: 50, Handler: testOperator}
|
var testOpType = &operationType{Type: "TEST", NumArgs: 1, Precedence: 50, Handler: testOperator}
|
||||||
var splitStringOpType = &operationType{Type: "SPLIT", NumArgs: 1, Precedence: 50, Handler: splitStringOperator}
|
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}
|
var loadOpType = &operationType{Type: "LOAD", NumArgs: 1, Precedence: 50, Handler: loadYamlOperator}
|
||||||
|
|
||||||
|
@ -9,6 +9,37 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"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) {
|
func getSubstituteParameters(d *dataTreeNavigator, block *ExpressionNode, context Context) (string, string, error) {
|
||||||
regEx := ""
|
regEx := ""
|
||||||
replacementText := ""
|
replacementText := ""
|
||||||
|
@ -5,6 +5,40 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var stringsOperatorScenarios = []expressionScenario{
|
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",
|
description: "Join strings",
|
||||||
document: `[cat, meow, 1, null, true]`,
|
document: `[cat, meow, 1, null, true]`,
|
||||||
|
Loading…
Reference in New Issue
Block a user