Skip to content

Commit

Permalink
foreach: fix command arg splitter pattern
Browse files Browse the repository at this point in the history
- add arguments section to usage text
- add comments explaining what each regex pattern does
- replace unwrap with ? operator
  • Loading branch information
jqnatividad committed Jul 30, 2023
1 parent af0a16a commit f18d686
Showing 1 changed file with 19 additions and 3 deletions.
22 changes: 19 additions & 3 deletions src/cmd/foreach.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![cfg(target_family = "unix")]
static USAGE: &str = r#"
Execute a shell command once per line in given CSV file. Only works in
Linux, macOS and other Unix-like environments.
Linux, macOS and other Unix-like environments (i.e. not Windows).
Deleting all files whose filenames are listed in a column:
Expand All @@ -21,6 +21,12 @@ Usage:
qsv foreach [options] <column> <command> [<input>]
qsv foreach --help
foreach arguments:
column The column to use as input for the command.
command The command to execute. Use "{}" to substitute the value
of the current input file line.
input The CSV file to read. If not provided, will read from stdin.
foreach options:
-u, --unify If the output of execute command is CSV, will
unify the result by skipping headers on each
Expand Down Expand Up @@ -77,8 +83,18 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
let mut wtr = Config::new(&None).writer()?;

#[allow(clippy::trivial_regex)]
// template_pattern matches pairs of curly braces, e.g. "{}".
let template_pattern = Regex::new(r"\{\}")?;
let splitter_pattern = Regex::new(r#"(?:[\w-]+|"[^"]*"|'[^']*'|`[^`]*`)"#)?;

// splitter_pattern gets all the arguments to the command as tokens.
// The regular expression matches any sequence of characters that consists of one or more word
// characters (`a-z`, `A-Z`, `0-9`, `_`, `.`, `+`, `-`), or any of the following three types of
// quoted strings: double-quoted strings ("..."), single-quoted strings ('...'), or
// backtick-quoted strings (`...`).
let splitter_pattern = Regex::new(r#"(?:[a-zA-Z0-9_.+-]+|"[^"]*"|'[^']*'|`[^`]*`)"#)?;

// cleaner_pattern removes the quotes or backticks from the quoted strings matched by
// splitter_pattern.
let cleaner_pattern = Regex::new(r#"(?:^["'`]|["'`]$)"#)?;

let headers = rdr.byte_headers()?.clone();
Expand Down Expand Up @@ -164,7 +180,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
}
}

cmd.wait().unwrap();
cmd.wait()?;
} else {
let mut cmd = Command::new(prog)
.args(cmd_args)
Expand Down

0 comments on commit f18d686

Please sign in to comment.