Repository: mikefarah/yq
Pull request #320 (2020-01-10 08:34:54)

#20 Read the top level keys only


Patch:
diff --git a/README.md b/README.md
index d8098ad5..63664bc4 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,21 @@ a lightweight and portable command-line YAML processor
 
 The aim of the project is to be the [jq](https://github.com/stedolan/jq) or sed of yaml files.
 
+
+## Major upgrade - V3 beta is out! 
+
+This addresses a number of features requests and issues that have been raised :)
+
+Currently only available only available as a [binary release here](https://github.com/mikefarah/yq/releases/tag/3.0.0-beta) or via docker mikefarah/yq:3.0.0-beta!
+
+It does have a few breaking changes listed on the [release page](https://github.com/mikefarah/yq/releases/tag/3.0.0-beta)
+
+Looking forward to feedback - once this is out of beta it will be added to the remaining package managers, and be the default version downloaded (and merged into master).
+
+V2 will no longer have any new features added, and will be moved to a branch (v2). It will have limited maintenance for bugs for a few months.
+
 ## Install
+
 ### On MacOS:
 ```
 brew install yq
@@ -21,16 +35,16 @@ snap install yq
 `yq` installs with with [_strict confinement_](https://docs.snapcraft.io/snap-confinement/6233) in snap, this means it doesn't have direct access to root files. To read root files you can:
 
 ```
-sudo cat /etc/myfile | yq -r - somecommand
+sudo cat /etc/myfile | yq r - a.path
 ```
 
 And to write to a root file you can either use [sponge](https://linux.die.net/man/1/sponge):
 ```
-sudo cat /etc/myfile | yq -r - somecommand | sudo sponge /etc/myfile
+sudo cat /etc/myfile | yq w - a.path value | sudo sponge /etc/myfile
 ```
 or write to a temporary file:
 ```
-sudo cat /etc/myfile | yq -r - somecommand | sudo tee /etc/myfile.tmp
+sudo cat /etc/myfile | yq w - a.path value | sudo tee /etc/myfile.tmp
 sudo mv /etc/myfile.tmp /etc/myfile
 rm /etc/myfile.tmp
 ```
diff --git a/yq.go b/yq.go
index d24d44c0..31154110 100644
--- a/yq.go
+++ b/yq.go
@@ -25,6 +25,7 @@ var writeInplace = false
 var writeScript = ""
 var outputToJSON = false
 var overwriteFlag = false
+var keyOnlyFlag = false
 var allowEmptyFlag = false
 var appendFlag = false
 var verbose = false
@@ -111,6 +112,7 @@ yq r -- things.yaml --key-starting-with-dashes
 	}
 	cmdRead.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
 	cmdRead.PersistentFlags().BoolVarP(&outputToJSON, "tojson", "j", false, "output as json")
+	cmdRead.PersistentFlags().BoolVarP(&keyOnlyFlag, "keyonly", "k", false, "output with top level keys only")
 	return cmdRead
 }
 
@@ -304,6 +306,13 @@ func readProperty(cmd *cobra.Command, args []string) error {
 		dataBucket = mappedDocs
 	}
 
+	if keyOnlyFlag {
+		for _, value := range dataBucket.(yaml.MapSlice) {
+			cmd.Println(value.Key)
+		}
+		return nil
+	}
+
 	dataStr, err := toString(dataBucket)
 	if err != nil {
 		return err


Test patch:
diff --git a/test/fixture/keyonly.yaml b/test/fixture/keyonly.yaml
new file mode 100644
index 00000000..f2dd3309
--- /dev/null
+++ b/test/fixture/keyonly.yaml
@@ -0,0 +1,6 @@
+a:
+  b:
+    c: 1
+  d:
+    e: 2
+  f:
diff --git a/yq_test.go b/yq_test.go
index 677f7bd0..05c78a94 100644
--- a/yq_test.go
+++ b/yq_test.go
@@ -1,12 +1,14 @@
 package main
 
 import (
+	"bytes"
 	"fmt"
 	"runtime"
 	"testing"
 
 	"github.com/mikefarah/yq/v2/pkg/marshal"
 	"github.com/mikefarah/yq/v2/test"
+	"github.com/spf13/cobra"
 )
 
 func TestMultilineString(t *testing.T) {
@@ -58,3 +60,27 @@ func TestNewYaml_WithUnknownScript(t *testing.T) {
 	}
 	test.AssertResult(t, expectedOutput, err.Error())
 }
+
+func TestReadWithKeyOnly(t *testing.T) {
+	readCmd := createReadCmd()
+	expectedResult := `b
+d
+f
+`
+	actualResult, err := executeTestCommand(readCmd, "test/fixture/keyonly.yaml", "a", "-k")
+	if err != nil {
+		t.Error(err.Error())
+	}
+	test.AssertResult(t, expectedResult, actualResult)
+}
+
+func executeTestCommand(command *cobra.Command, args ...string) (output string, err error) {
+	buf := new(bytes.Buffer)
+
+	command.SetOutput(buf)
+	command.SetArgs(args)
+
+	_, err = command.ExecuteC()
+
+	return buf.String(), err
+}