mirror of
https://github.com/rclone/rclone.git
synced 2024-11-26 02:09:55 +08:00
cat: adds --separator option to cat command
When using `rclone cat` to print the contents of several files, the user may want to inject some separator between the files, such as a comma or a newline. This patch adds a `--separator` option to the `cat` command to make that possible. The default value remains an empty string, `""`, maintaining the prior behavior of `rclone cat`. Closes #6968
This commit is contained in:
parent
db8c007983
commit
3e15a594b7
|
@ -824,8 +824,9 @@ func touchFiles(ctx context.Context, dateStr string, f fs.Fs, dir, glob string)
|
|||
err = nil
|
||||
buf := new(bytes.Buffer)
|
||||
size := obj.Size()
|
||||
separator := ""
|
||||
if size > 0 {
|
||||
err = operations.Cat(ctx, f, buf, 0, size)
|
||||
err = operations.Cat(ctx, f, buf, 0, size, []byte(separator))
|
||||
}
|
||||
info := object.NewStaticObjectInfo(remote, date, size, true, nil, f)
|
||||
if err == nil {
|
||||
|
|
|
@ -21,6 +21,7 @@ var (
|
|||
offset = int64(0)
|
||||
count = int64(-1)
|
||||
discard = false
|
||||
separator = string("")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -31,6 +32,7 @@ func init() {
|
|||
flags.Int64VarP(cmdFlags, &offset, "offset", "", offset, "Start printing at offset N (or from end if -ve)")
|
||||
flags.Int64VarP(cmdFlags, &count, "count", "", count, "Only print N characters")
|
||||
flags.BoolVarP(cmdFlags, &discard, "discard", "", discard, "Discard the output instead of printing")
|
||||
flags.StringVarP(cmdFlags, &separator, "separator", "", separator, "Separator to use between objects when printing multiple files")
|
||||
}
|
||||
|
||||
var commandDefinition = &cobra.Command{
|
||||
|
@ -56,6 +58,18 @@ Use the |--head| flag to print characters only at the start, |--tail| for
|
|||
the end and |--offset| and |--count| to print a section in the middle.
|
||||
Note that if offset is negative it will count from the end, so
|
||||
|--offset -1 --count 1| is equivalent to |--tail 1|.
|
||||
|
||||
Use the |--separator| flag to print a separator value between files. Be sure to
|
||||
shell-escape special characters. For example, to print a newline between
|
||||
files, use:
|
||||
|
||||
* bash:
|
||||
|
||||
rclone --include "*.txt" --separator $'\n' cat remote:path/to/dir
|
||||
|
||||
* powershell:
|
||||
|
||||
rclone --include "*.txt" --separator "|n" cat remote:path/to/dir
|
||||
`, "|", "`"),
|
||||
Annotations: map[string]string{
|
||||
"versionIntroduced": "v1.33",
|
||||
|
@ -82,7 +96,7 @@ Note that if offset is negative it will count from the end, so
|
|||
w = io.Discard
|
||||
}
|
||||
cmd.Run(false, false, command, func() error {
|
||||
return operations.Cat(context.Background(), fsrc, w, offset, count)
|
||||
return operations.Cat(context.Background(), fsrc, w, offset, count, []byte(separator))
|
||||
})
|
||||
},
|
||||
}
|
||||
|
|
|
@ -32,6 +32,18 @@ the end and `--offset` and `--count` to print a section in the middle.
|
|||
Note that if offset is negative it will count from the end, so
|
||||
`--offset -1 --count 1` is equivalent to `--tail 1`.
|
||||
|
||||
Use the `--separator` flag to print a separator value between files. Be sure to
|
||||
shell-escape special characters. For example, to print a newline between
|
||||
files, use:
|
||||
|
||||
* bash:
|
||||
|
||||
rclone --include "*.txt" --separator $'\n' cat remote:path/to/dir
|
||||
|
||||
* powershell:
|
||||
|
||||
rclone --include "*.txt" --separator "`n" cat remote:path/to/dir
|
||||
|
||||
|
||||
```
|
||||
rclone cat remote:path [flags]
|
||||
|
@ -45,6 +57,7 @@ rclone cat remote:path [flags]
|
|||
--head int Only print the first N characters
|
||||
-h, --help help for cat
|
||||
--offset int Start printing at offset N (or from end if -ve)
|
||||
--separator string Separator to use between objects when printing multiple files
|
||||
--tail int Only print the last N characters
|
||||
```
|
||||
|
||||
|
|
|
@ -1259,7 +1259,7 @@ type readCloser struct {
|
|||
//
|
||||
// if count < 0 then it will be ignored
|
||||
// if count >= 0 then only that many characters will be output
|
||||
func Cat(ctx context.Context, f fs.Fs, w io.Writer, offset, count int64) error {
|
||||
func Cat(ctx context.Context, f fs.Fs, w io.Writer, offset, count int64, sep []byte) error {
|
||||
var mu sync.Mutex
|
||||
ci := fs.GetConfig(ctx)
|
||||
return ListFn(ctx, f, func(o fs.Object) {
|
||||
|
@ -1301,6 +1301,13 @@ func Cat(ctx context.Context, f fs.Fs, w io.Writer, offset, count int64) error {
|
|||
err = fs.CountError(err)
|
||||
fs.Errorf(o, "Failed to send to output: %v", err)
|
||||
}
|
||||
if len(sep) >= 0 {
|
||||
_, err = w.Write(sep)
|
||||
if err != nil {
|
||||
err = fs.CountError(err)
|
||||
fs.Errorf(o, "Failed to send separator to output: %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -531,21 +531,23 @@ func TestCat(t *testing.T) {
|
|||
for _, test := range []struct {
|
||||
offset int64
|
||||
count int64
|
||||
separator string
|
||||
a string
|
||||
b string
|
||||
}{
|
||||
{0, -1, "ABCDEFGHIJ", "012345678"},
|
||||
{0, 5, "ABCDE", "01234"},
|
||||
{-3, -1, "HIJ", "678"},
|
||||
{1, 3, "BCD", "123"},
|
||||
{0, -1, "", "ABCDEFGHIJ", "012345678"},
|
||||
{0, 5, "", "ABCDE", "01234"},
|
||||
{-3, -1, "", "HIJ", "678"},
|
||||
{1, 3, "", "BCD", "123"},
|
||||
{0, -1, "\n", "ABCDEFGHIJ", "012345678"},
|
||||
} {
|
||||
var buf bytes.Buffer
|
||||
err := operations.Cat(ctx, r.Fremote, &buf, test.offset, test.count)
|
||||
err := operations.Cat(ctx, r.Fremote, &buf, test.offset, test.count, []byte(test.separator))
|
||||
require.NoError(t, err)
|
||||
res := buf.String()
|
||||
|
||||
if res != test.a+test.b && res != test.b+test.a {
|
||||
t.Errorf("Incorrect output from Cat(%d,%d): %q", test.offset, test.count, res)
|
||||
if res != test.a+test.separator+test.b+test.separator && res != test.b+test.separator+test.a+test.separator {
|
||||
t.Errorf("Incorrect output from Cat(%d,%d,%s): %q", test.offset, test.count, test.separator, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user