1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use clap::{Parser, Subcommand};
#[derive(Subcommand, Debug)]
pub enum CaseStyle {
/// lowercase
Lower,
/// UPPERCASE
Upper,
}
#[derive(Parser, Debug)]
#[command(about = "Cli for common string operations. Takes input from stdin.")]
pub enum StringCommand {
/// Transform upper- or lowercase
#[command(subcommand)]
Case(CaseStyle),
/// Reverse order of lines
Reverse,
/// Extract part of a given string.
Substr {
#[arg()]
start: usize,
#[arg()]
end: usize,
},
/// Split up a string by a separator and print the parts on separate lines
Split {
#[arg(default_value = " ")]
separator: String,
},
/// Join lines with a separator into a single string
Join {
#[arg(default_value = " ")]
separator: String,
},
/// Print all lines containing the given string
Contains {
/// print all lines that are NOT matching
#[arg(default_value = "false", short = 'n', long = "not")]
not: bool,
#[arg()]
pattern: String,
},
/// Print all lines starting with the given prefix, ignoring leading whitespace
StartsWith {
/// print all lines that are NOT matching
#[arg(default_value = "false", short = 'n', long = "not")]
not: bool,
#[arg()]
prefix: String,
},
/// Print all lines ending with the given suffix, ignoring trailing whitespace
EndsWith {
/// print all lines that are NOT matching
#[arg(default_value = "false", short = 'n', long = "not")]
not: bool,
#[arg()]
suffix: String,
},
/// Returns the length the input string
Length,
/// Replace all matching characters
Replace {
#[arg()]
matching: String,
#[arg()]
with: String,
},
/// Pick a single line by index
Line {
#[arg()]
/// starting at 0
number: usize,
},
/// Interleave input and only print every nth line
Interleave {
#[arg()]
/// starting at 0
n: usize,
},
/// Output the set of input strings without repetitions, in order
Distinct {
#[arg(short)]
/// Distinct entire lines, instead of individual words
lines: bool,
},
/// Trim whitespace on lines and ignore empty ones
Trim,
/// Prints all chars on separate lines
Chars,
/// Useful for templating, replace sections of input with the output of a shell command or script
Template {
#[arg(default_value = "{{", long = "begin")]
/// Delimiter indicating beginning of command
begin: String,
#[arg(default_value = "}}", long = "end")]
/// Delimiter indicating end of command
end: String,
#[arg(default_value = "sh", long)]
/// in which shell the commands should be piped
shell: Vec<String>,
#[arg(long = "raw-output")]
/// don't trim new lines and whitespace of the start and end of output
raw_output: bool,
},
/// Map each line of input to a subcommand. Can be used to parallelize work
Each {
/// If set, input will be passed to subcommand via stdin (default is replacing part of the
/// command with the input)
#[arg(short = 's', long = "stdin", default_value_t = false)]
stdin: bool,
/// Name of placeholder in command to be replaced with input. Default is "{}"
#[arg(short = 'v', long = "var", default_value = "{}")]
var: String,
/// Number of commands to run in parallel. The default of 1 runs them one after another
#[arg(short = 't', long = "threads", default_value_t = 1)]
threads: usize,
/// Print the results in the order of the input, instead of the order they finish in.
/// Waits for earlier lines, so a single slow command holds back everything behind it
#[arg(long = "sequential", default_value_t = false)]
sequential: bool,
/// Command to be executed. Pass "string each -- <commands...>" so you can pass flags to the command.
command: Vec<String>,
},
}