mirror of
https://github.com/mikefarah/yq.git
synced 2026-08-24 08:22:13 +08:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0c3da1262 | ||
|
|
7696aeb560 |
+1
-2
@@ -1,2 +1 @@
|
||||
a:
|
||||
include: 'data2.yaml'
|
||||
["a a", "b thing", 1, true]
|
||||
@@ -0,0 +1,38 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type csvEncoder struct {
|
||||
destination csv.Writer
|
||||
}
|
||||
|
||||
func NewCsvEncoder(destination io.Writer, separator rune) Encoder {
|
||||
csvWriter := *csv.NewWriter(destination)
|
||||
csvWriter.Comma = separator
|
||||
return &csvEncoder{csvWriter}
|
||||
}
|
||||
|
||||
func (e *csvEncoder) Encode(originalNode *yaml.Node) error {
|
||||
// node must be a sequence
|
||||
node := unwrapDoc(originalNode)
|
||||
if node.Kind != yaml.SequenceNode {
|
||||
return fmt.Errorf("csv encoding only works for arrays of scalars (string/numbers/booleans), got: %v", node.Tag)
|
||||
}
|
||||
|
||||
stringValues := make([]string, len(node.Content))
|
||||
|
||||
for i, child := range node.Content {
|
||||
|
||||
if child.Kind != yaml.ScalarNode {
|
||||
return fmt.Errorf("csv encoding only works for arrays of scalars (string/numbers/booleans), child[%v] is a %v", i, child.Tag)
|
||||
}
|
||||
stringValues[i] = child.Value
|
||||
}
|
||||
return e.destination.Write(stringValues)
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mikefarah/yq/v4/test"
|
||||
)
|
||||
|
||||
func yamlToCsv(sampleYaml string, separator rune) string {
|
||||
var output bytes.Buffer
|
||||
writer := bufio.NewWriter(&output)
|
||||
|
||||
var jsonEncoder = NewCsvEncoder(writer, separator)
|
||||
inputs, err := readDocuments(strings.NewReader(sampleYaml), "sample.yml", 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
node := inputs.Front().Value.(*CandidateNode).Node
|
||||
err = jsonEncoder.Encode(node)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
writer.Flush()
|
||||
|
||||
return strings.TrimSuffix(output.String(), "\n")
|
||||
}
|
||||
|
||||
var sampleYaml = `["apple", apple2, "comma, in, value", "new
|
||||
line", 3, 3.40, true, "tab here"]`
|
||||
|
||||
func TestCsvEncoder(t *testing.T) {
|
||||
var expectedCsv = `apple,apple2,"comma, in, value",new line,3,3.40,true,tab here`
|
||||
|
||||
var actualCsv = yamlToCsv(sampleYaml, ',')
|
||||
test.AssertResult(t, expectedCsv, actualCsv)
|
||||
}
|
||||
|
||||
func TestTsvEncoder(t *testing.T) {
|
||||
|
||||
var expectedCsv = `apple apple2 comma, in, value new line 3 3.40 true "tab here"`
|
||||
|
||||
var actualCsv = yamlToCsv(sampleYaml, '\t')
|
||||
test.AssertResult(t, expectedCsv, actualCsv)
|
||||
}
|
||||
@@ -325,11 +325,21 @@ func initLexer() (*lex.Lexer, error) {
|
||||
lexer.Add([]byte(`to_json\([0-9]+\)`), encodeWithIndent(JsonOutputFormat))
|
||||
|
||||
lexer.Add([]byte(`toyaml`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: YamlOutputFormat, indent: 2}))
|
||||
lexer.Add([]byte(`@yaml`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: YamlOutputFormat, indent: 0}))
|
||||
|
||||
lexer.Add([]byte(`tojson`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: JsonOutputFormat, indent: 2}))
|
||||
lexer.Add([]byte(`toprops`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: PropsOutputFormat, indent: 2}))
|
||||
|
||||
lexer.Add([]byte(`to_yaml`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: YamlOutputFormat, indent: 2}))
|
||||
lexer.Add([]byte(`to_json`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: JsonOutputFormat, indent: 2}))
|
||||
lexer.Add([]byte(`@json`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: JsonOutputFormat, indent: 0}))
|
||||
|
||||
lexer.Add([]byte(`to_csv`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: CsvOutputFormat}))
|
||||
lexer.Add([]byte(`@csv`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: CsvOutputFormat}))
|
||||
|
||||
lexer.Add([]byte(`to_tsv`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: TsvOutputFormat}))
|
||||
lexer.Add([]byte(`@tsv`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: TsvOutputFormat}))
|
||||
|
||||
lexer.Add([]byte(`to_props`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: PropsOutputFormat, indent: 2}))
|
||||
|
||||
lexer.Add([]byte(`fromyaml`), opToken(decodeOpType))
|
||||
|
||||
+16
-4
@@ -23,6 +23,8 @@ const (
|
||||
YamlOutputFormat = 1 << iota
|
||||
JsonOutputFormat
|
||||
PropsOutputFormat
|
||||
CsvOutputFormat
|
||||
TsvOutputFormat
|
||||
)
|
||||
|
||||
func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
|
||||
@@ -33,8 +35,12 @@ func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
|
||||
return JsonOutputFormat, nil
|
||||
case "props", "p":
|
||||
return PropsOutputFormat, nil
|
||||
case "csv", "c":
|
||||
return CsvOutputFormat, nil
|
||||
case "tsv", "t":
|
||||
return TsvOutputFormat, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("Unknown fromat '%v' please use [yaml|json|props]", format)
|
||||
return 0, fmt.Errorf("unknown format '%v' please use [yaml|json|props|csv|tsv]", format)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,13 +93,19 @@ func (p *resultsPrinter) printNode(node *yaml.Node, writer io.Writer) error {
|
||||
return writeString(writer, node.Value+"\n")
|
||||
}
|
||||
|
||||
if p.outputFormat == JsonOutputFormat {
|
||||
switch p.outputFormat {
|
||||
case JsonOutputFormat:
|
||||
encoder = NewJsonEncoder(writer, p.indent)
|
||||
} else if p.outputFormat == PropsOutputFormat {
|
||||
case PropsOutputFormat:
|
||||
encoder = NewPropertiesEncoder(writer)
|
||||
} else {
|
||||
case CsvOutputFormat:
|
||||
encoder = NewCsvEncoder(writer, ',')
|
||||
case TsvOutputFormat:
|
||||
encoder = NewCsvEncoder(writer, '\t')
|
||||
case YamlOutputFormat:
|
||||
encoder = NewYamlEncoder(writer, p.indent, p.colorsEnabled)
|
||||
}
|
||||
|
||||
return encoder.Encode(node)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
# load array into a bash array
|
||||
# need to output each entry as a single line
|
||||
# readarray identityMappings < <(./yq e -o=j -I=0 '.identitymappings[]' test.yml )
|
||||
|
||||
# for identityMapping in "${identityMappings[@]}"; do
|
||||
# # identity mapping is a yaml snippet representing a single entry
|
||||
# roleArn=$(echo "$identityMapping" | yq e '.arn' -)
|
||||
# echo "roleArn: $roleArn"
|
||||
# done
|
||||
|
||||
|
||||
|
||||
|
||||
while IFS=$'\t' read -r roleArn group user _; do
|
||||
echo "Role: $roleArn"
|
||||
echo "Group: $group"
|
||||
echo "User: $user"
|
||||
done < <(yq -j read test.yaml \
|
||||
| jq -r '.identitymappings[] | [.arn, .group, .user] | @tsv')
|
||||
Reference in New Issue
Block a user