mirror of
https://github.com/rclone/rclone.git
synced 2024-11-23 03:17:28 +08:00
lsf: Add --csv flag for compliant CSV output
This commit is contained in:
parent
2a32e2d838
commit
e56be0dfd8
|
@ -23,6 +23,7 @@ var (
|
|||
hashType = hash.MD5
|
||||
filesOnly bool
|
||||
dirsOnly bool
|
||||
csv bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -34,6 +35,7 @@ func init() {
|
|||
flags.VarP(&hashType, "hash", "", "Use this hash when `h` is used in the format MD5|SHA-1|DropboxHash")
|
||||
flags.BoolVarP(&filesOnly, "files-only", "", false, "Only list files.")
|
||||
flags.BoolVarP(&dirsOnly, "dirs-only", "", false, "Only list directories.")
|
||||
flags.BoolVarP(&csv, "csv", "", false, "Output in CSV format.")
|
||||
commandDefintion.Flags().BoolVarP(&recurse, "recursive", "R", false, "Recurse into the listing.")
|
||||
}
|
||||
|
||||
|
@ -113,11 +115,28 @@ Eg
|
|||
2018-04-26 08:52:53,0,,ferejej3gux/
|
||||
2016-06-25 18:55:40,37600,8fd37c3810dd660778137ac3a66cc06d,fubuwic
|
||||
|
||||
You can output in CSV standard format. This will escape things in "
|
||||
if they contain ,
|
||||
|
||||
Eg
|
||||
|
||||
$ rclone lsf --csv --files-only --format ps remote:path
|
||||
test.log,22355
|
||||
test.sh,449
|
||||
"this file contains a comma, in the file name.txt",6
|
||||
|
||||
` + lshelp.Help,
|
||||
Run: func(command *cobra.Command, args []string) {
|
||||
cmd.CheckArgs(1, 1, command, args)
|
||||
fsrc := cmd.NewFsSrc(args)
|
||||
cmd.Run(false, false, command, func() error {
|
||||
// Work out if the separatorFlag was supplied or not
|
||||
separatorFlag := command.Flags().Lookup("separator")
|
||||
separatorFlagSupplied := separatorFlag != nil && separatorFlag.Changed
|
||||
// Default the separator to , if using CSV
|
||||
if csv && !separatorFlagSupplied {
|
||||
separator = ","
|
||||
}
|
||||
return Lsf(fsrc, os.Stdout)
|
||||
})
|
||||
},
|
||||
|
@ -128,6 +147,7 @@ Eg
|
|||
func Lsf(fsrc fs.Fs, out io.Writer) error {
|
||||
var list operations.ListFormat
|
||||
list.SetSeparator(separator)
|
||||
list.SetCSV(csv)
|
||||
list.SetDirSlash(dirSlash)
|
||||
|
||||
for _, char := range format {
|
||||
|
|
|
@ -4,6 +4,7 @@ package operations
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -1368,6 +1369,8 @@ type ListFormat struct {
|
|||
dirSlash bool
|
||||
output []func() string
|
||||
entry fs.DirEntry
|
||||
csv *csv.Writer
|
||||
buf bytes.Buffer
|
||||
}
|
||||
|
||||
// SetSeparator changes separator in struct
|
||||
|
@ -1380,6 +1383,21 @@ func (l *ListFormat) SetDirSlash(dirSlash bool) {
|
|||
l.dirSlash = dirSlash
|
||||
}
|
||||
|
||||
// SetCSV defines if the output should be csv
|
||||
//
|
||||
// Note that you should call SetSeparator before this if you want a
|
||||
// custom separator
|
||||
func (l *ListFormat) SetCSV(useCSV bool) {
|
||||
if useCSV {
|
||||
l.csv = csv.NewWriter(&l.buf)
|
||||
if l.separator != "" {
|
||||
l.csv.Comma = []rune(l.separator)[0]
|
||||
}
|
||||
} else {
|
||||
l.csv = nil
|
||||
}
|
||||
}
|
||||
|
||||
// SetOutput sets functions used to create files information
|
||||
func (l *ListFormat) SetOutput(output []func() string) {
|
||||
l.output = output
|
||||
|
@ -1439,18 +1457,23 @@ func (l *ListFormat) AddMimeType() {
|
|||
|
||||
// AppendOutput adds string generated by specific function to printed output
|
||||
func (l *ListFormat) AppendOutput(functionToAppend func() string) {
|
||||
if len(l.output) > 0 {
|
||||
l.output = append(l.output, func() string { return l.separator })
|
||||
}
|
||||
l.output = append(l.output, functionToAppend)
|
||||
}
|
||||
|
||||
// Format prints information about the DirEntry in the format defined
|
||||
func (l *ListFormat) Format(entry fs.DirEntry) string {
|
||||
func (l *ListFormat) Format(entry fs.DirEntry) (result string) {
|
||||
l.entry = entry
|
||||
var out string
|
||||
var out []string
|
||||
for _, fun := range l.output {
|
||||
out += fun()
|
||||
out = append(out, fun())
|
||||
}
|
||||
return out
|
||||
if l.csv != nil {
|
||||
l.buf.Reset()
|
||||
_ = l.csv.Write(out) // can't fail writing to bytes.Buffer
|
||||
l.csv.Flush()
|
||||
result = strings.TrimRight(l.buf.String(), "\n")
|
||||
} else {
|
||||
result = strings.Join(out, l.separator)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -747,4 +747,15 @@ func TestListFormat(t *testing.T) {
|
|||
assert.Equal(t, test.want, got)
|
||||
}
|
||||
}
|
||||
|
||||
list.SetOutput(nil)
|
||||
list.SetSeparator("|")
|
||||
list.SetCSV(true)
|
||||
list.AddSize()
|
||||
list.AddPath()
|
||||
list.AddModTime()
|
||||
list.SetDirSlash(true)
|
||||
assert.Equal(t, "1|a|"+items[0].ModTime().Local().Format("2006-01-02 15:04:05"), list.Format(items[0]))
|
||||
assert.Equal(t, fmt.Sprintf("%d", items[1].Size())+"|subdir/|"+items[1].ModTime().Local().Format("2006-01-02 15:04:05"), list.Format(items[1]))
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user