Skip to content

Commit

Permalink
Changed a few defaults and added a new option.
Browse files Browse the repository at this point in the history
Changed the default seperator to '>' for easier use with "cut".

Removed the ability to change the string wrapper in order to leverage
the strconv.Quote functionality which will escape all of the special
characters in a string in order to ensure everything stays on one line.

Now hiding the keys by default. Added an option to display them.
  • Loading branch information
AndrewGuenther committed May 3, 2015
1 parent 911d55b commit 7293639
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 33 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ all: build
build:
${GO} build -o ./jsonf

install: build
cp ./jsonf /usr/bin/

clean: ./jsonf
rm -rf jsonf
rm -rf ./jsonf
33 changes: 17 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,27 @@ Usage of jsonf:
-a="[]": The runes used to wrap output array indexes.
-i="": The input file. Defaults to stdin.
-k="{}": The runes used to wrap output keys.
-keys=false: If true, keys are printed on their own line.
-o="": The output file. Defaults to stdout.
-s="\"\"": The runes used to wrap output strings.
-sep="->": String used to seperate keys.
-sep=">": String used to seperate keys.
```

```bash
$ jsonf
$ jsonf --keys
{"colors": ["red", "blue", "green"], "numbers": [1, 2, 3], "active": true}
->{active}
->{active}->true
->{colors}
->{colors}->[]
->{colors}->[0]->"red"
->{colors}->[1]->"blue"
->{colors}->[2]->"green"
->{numbers}
->{numbers}->[]
->{numbers}->[0]->1
->{numbers}->[1]->2
->{numbers}->[2]->3
>{active}
>{active}>true
>{colors}
>{colors}>[]
>{colors}>[0]>"red"
>{colors}>[1]>"blue"
>{colors}>[2]>"green"
>{numbers}
>{numbers}>[]
>{numbers}>[0]>1
>{numbers}>[1]>2
>{numbers}>[2]>3
```

# Examples
Expand All @@ -39,7 +40,7 @@ $ jsonf

```bash
$ curl -s 'https://api.github.com/repos/andrewguenther/jsonf/commits' |
jsonf -sep='>' |
jsonf |
grep -a "\[0\].*{commit}>{committer}>.*>" |
cut -d ">" -f 5,6
{name}>"Andrew Guenther"
Expand All @@ -51,7 +52,7 @@ $ curl -s 'https://api.github.com/repos/andrewguenther/jsonf/commits' |

```bash
$ curl -s 'https://www.reddit.com/.json' |
jsonf -sep='>' |
jsonf |
grep '>{data}>{children}>\[.\+\]>{data}>{url}>' |
cut -d '>' -f 7
"https://i.imgur.com/qH91IEl.gifv"
Expand Down
34 changes: 18 additions & 16 deletions jsonf.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"log"
"os"
"strconv"
)

func main() {
Expand All @@ -22,12 +23,12 @@ func main() {
}

type JsonfOptions struct {
decoder *json.Decoder
output io.Writer
keyWrap string
strWrap string
arrWrap string
seperator string
decoder *json.Decoder
output io.Writer
keyWrap string
arrWrap string
seperator string
includeKeys bool
}

func HandleArgs(opts *JsonfOptions) {
Expand All @@ -36,9 +37,9 @@ func HandleArgs(opts *JsonfOptions) {
var outputFile string
flag.StringVar(&outputFile, "o", "", "The output file. Defaults to stdout.")
flag.StringVar(&opts.keyWrap, "k", "{}", "The runes used to wrap output keys.")
flag.StringVar(&opts.strWrap, "s", "\"\"", "The runes used to wrap output strings.")
flag.StringVar(&opts.arrWrap, "a", "[]", "The runes used to wrap output array indexes.")
flag.StringVar(&opts.seperator, "sep", "->", "String used to seperate keys.")
flag.StringVar(&opts.seperator, "sep", ">", "String used to seperate keys.")
flag.BoolVar(&opts.includeKeys, "keys", false, "If true, keys are printed on their own line.")

flag.Parse()

Expand All @@ -61,16 +62,13 @@ func HandleArgs(opts *JsonfOptions) {
if len(opts.keyWrap) != 2 {
panic("-k must contain exactly two characters")
}
if len(opts.strWrap) != 2 {
panic("-s must contain exactly two characters")
}
if len(opts.arrWrap) != 2 {
panic("-a must contain exactly two characters")
}
}

func Jsonf(opts JsonfOptions) {
for {
for numReads := 0; ; numReads++ {
var json interface{}
if err := opts.decoder.Decode(&json); err != nil {
if err.Error() != "EOF" {
Expand All @@ -79,7 +77,7 @@ func Jsonf(opts JsonfOptions) {
return
}
}
ProcessJsonValue(opts, "", json)
ProcessJsonValue(opts, strconv.Itoa(numReads), json)
}
}

Expand All @@ -88,17 +86,21 @@ func ProcessJsonValue(opts JsonfOptions, leadKey string, json interface{}) {
case map[string]interface{}:
for key, value := range json.(map[string]interface{}) {
keyLead := fmt.Sprintf("%s%s%c%s%c", leadKey, opts.seperator, opts.keyWrap[0], key, opts.keyWrap[1])
fmt.Fprintln(opts.output, keyLead)
if opts.includeKeys {
fmt.Fprintln(opts.output, keyLead)
}
ProcessJsonValue(opts, keyLead, value)
}
case []interface{}:
fmt.Fprintf(opts.output, "%s%s%c%c\n", leadKey, opts.seperator, opts.arrWrap[0], opts.arrWrap[1])
if opts.includeKeys {
fmt.Fprintf(opts.output, "%s%s%c%c\n", leadKey, opts.seperator, opts.arrWrap[0], opts.arrWrap[1])
}
for index, value := range json.([]interface{}) {
elemLead := fmt.Sprintf("%s%s%c%d%c", leadKey, opts.seperator, opts.arrWrap[0], index, opts.arrWrap[1])
ProcessJsonValue(opts, elemLead, value)
}
case string:
fmt.Fprintf(opts.output, "%s%s%c%s%c\n", leadKey, opts.seperator, opts.strWrap[0], json, opts.strWrap[1])
fmt.Fprintf(opts.output, "%s%s%s\n", leadKey, opts.seperator, strconv.Quote(json.(string)))
default:
fmt.Fprintf(opts.output, "%s%s%v\n", leadKey, opts.seperator, json)
}
Expand Down

0 comments on commit 7293639

Please sign in to comment.