Added csv, tsv output formats

This commit is contained in:
Mike Farah 2021-12-01 12:08:47 +11:00
parent 3126724eaf
commit d0419ceedf
5 changed files with 85 additions and 6 deletions

View File

@ -1,2 +1 @@
a:
include: 'data2.yaml'
["a a", "b thing", 1, true]

38
pkg/yqlib/encoder_csv.go Normal file
View File

@ -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)
}

View File

@ -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))

View File

@ -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)
}

20
test.sh Executable file
View File

@ -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')