mirror of
https://github.com/acaloiaro/struct
synced 2026-07-21 10:12:28 +00:00
Initial commit
This commit is contained in:
commit
317e69024b
3 changed files with 170 additions and 0 deletions
22
README.md
Normal file
22
README.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# struct
|
||||
|
||||
A simple unix utility for structuring string data on the command line.
|
||||
|
||||
# example usage
|
||||
|
||||
## string output
|
||||
```
|
||||
$ ls -l | struct -fields permissions,count,user,group,,,,,file_name -output string
|
||||
permissions:-rw-r--r-- count:1 user:adriano group:staff 84 Sep 23 22:55 file_name:README.md
|
||||
permissions:-rw------- count:1 user:adriano group:staff 39 Sep 23 21:08 file_name:go.mod
|
||||
permissions:-rw-r--r-- count:1 user:adriano group:staff 2531 Sep 23 22:54 file_name:struct.go
|
||||
```
|
||||
|
||||
## json output
|
||||
|
||||
```bash
|
||||
$ ls -l | struct -fields permissions,count,user,group,,,,,file_name -output json
|
||||
{"count":"1","file_name":"README.md","group":"staff","permissions":"-rw-r--r--","user":"adriano"}
|
||||
{"count":"1","file_name":"go.mod","group":"staff","permissions":"-rw-------","user":"adriano"}
|
||||
{"count":"1","file_name":"struct.go","group":"staff","permissions":"-rw-r--r--","user":"adriano"}
|
||||
```
|
||||
3
go.mod
Normal file
3
go.mod
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module adriano.fyi/pkg/struct
|
||||
|
||||
go 1.12
|
||||
145
struct.go
Normal file
145
struct.go
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type fields []string
|
||||
|
||||
var fieldsFlag fields
|
||||
var sepFlag string
|
||||
var outFlag string
|
||||
|
||||
var in string
|
||||
var fieldsProvided int
|
||||
|
||||
func (f *fields) String() string {
|
||||
return fmt.Sprint(*f)
|
||||
}
|
||||
|
||||
func (f *fields) Set(value string) error {
|
||||
if len(*f) > 0 {
|
||||
return errors.New("fields switch already set")
|
||||
}
|
||||
|
||||
for _, field := range strings.Split(value, ",") {
|
||||
*f = append(*f, field)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
defaultFieldSeparator = " "
|
||||
defaultOutput = "string"
|
||||
fieldsUsage = "comma-separated list of fields corresponding to the input data's fields\n\n" +
|
||||
"Example\n\n" +
|
||||
"$ echo \"foo1 bar1\" | struct -fields foo,bar\n" +
|
||||
"$ foo:foo1 bar:bar1\n"
|
||||
outputUsage = "the desired output format: json or string"
|
||||
separatorUsage = "the character that separates fields in the input data"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
flag.Var(&fieldsFlag, "fields", fieldsUsage)
|
||||
flag.StringVar(&sepFlag, "separator", defaultFieldSeparator, separatorUsage)
|
||||
flag.StringVar(&outFlag, "output", defaultOutput, outputUsage)
|
||||
setupFlags(flag.CommandLine)
|
||||
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func setupFlags(f *flag.FlagSet) {
|
||||
f.Usage = func() {
|
||||
fmt.Println("\nCreate structured data input strings")
|
||||
|
||||
f.PrintDefaults()
|
||||
}
|
||||
}
|
||||
|
||||
var sb strings.Builder
|
||||
var jsonMap = make(map[string]string)
|
||||
|
||||
func main() {
|
||||
fieldsProvided = len(fieldsFlag)
|
||||
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
|
||||
var i int
|
||||
var field, v string
|
||||
|
||||
for scanner.Scan() {
|
||||
in = scanner.Text()
|
||||
|
||||
inputFields := strings.Fields(in)
|
||||
|
||||
for i, v = range inputFields {
|
||||
if i < fieldsProvided {
|
||||
|
||||
field = fieldsFlag[i]
|
||||
} else {
|
||||
field = ""
|
||||
}
|
||||
|
||||
buildOutput(field, v)
|
||||
}
|
||||
|
||||
fmt.Println(out())
|
||||
}
|
||||
}
|
||||
|
||||
func out() (out string) {
|
||||
if outFlag == "string" {
|
||||
out = sb.String()
|
||||
sb.Reset()
|
||||
} else if outFlag == "json" {
|
||||
o, _ := json.Marshal(jsonMap)
|
||||
out = string(o)
|
||||
for k := range jsonMap {
|
||||
delete(jsonMap, k)
|
||||
}
|
||||
} else {
|
||||
out = ""
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func buildOutput(field, value string) error {
|
||||
if outFlag == "string" {
|
||||
buildString(field, value)
|
||||
} else if outFlag == "json" {
|
||||
buildJSON(field, value)
|
||||
} else {
|
||||
return errors.New("invalid output option")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildString(field, value string) {
|
||||
if field != "" {
|
||||
sb.WriteString(field)
|
||||
sb.WriteString(":")
|
||||
sb.WriteString(value)
|
||||
sb.WriteString(sepFlag)
|
||||
} else {
|
||||
sb.WriteString(value)
|
||||
sb.WriteString(sepFlag)
|
||||
}
|
||||
}
|
||||
|
||||
func buildJSON(field, value string) {
|
||||
if field == "" {
|
||||
return
|
||||
}
|
||||
|
||||
jsonMap[field] = value
|
||||
}
|
||||
Loading…
Reference in a new issue