Skip to content

Commit

Permalink
Adding xan search --all
Browse files Browse the repository at this point in the history
  • Loading branch information
Yomguithereal committed Feb 5, 2025
1 parent 0a0de20 commit 3dac3e9
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/cmd/cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ cluster options:
Common options:
-h, --help Display this message
-o, --output <file> Write output to <file> instead of stdout.
-n, --no-headers When set, the first row will not be evaled
as headers.
-d, --delimiter <arg> The field delimiter for reading CSV data.
Expand Down
18 changes: 17 additions & 1 deletion docs/cmd/search.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@
# xan search

```txt
Filter rows of given CSV file if some of its cells contains a desired substring.
Keep rows of given CSV file if ANY of the selected columns contains a desired
substring.
Can also be used to search for exact matches using the -e, --exact flag.
Can also be used to search using a regular expression using the -r, --regex flag.
Can also be used to search for empty or non-empty selections. For instance,
keeping only rows where selection is not fully empty:
$ xan search --non-empty file.csv
Or keeping only rows where selection has any empty column:
$ xan search --empty file.csv
When using a regular expression, be sure to mind bash escape rules (prefer single
quotes around your expression and don't forget to use backslashes when needed):
Expand Down Expand Up @@ -39,13 +49,16 @@ Feeding CSV column as patterns through stdin (using "-"):
Usage:
xan search [options] --non-empty [<input>]
xan search [options] --empty [<input>]
xan search [options] --patterns <index> [<input>]
xan search [options] <pattern> [<input>]
xan search --help
search options:
-e, --exact Perform an exact match.
-r, --regex Use a regex to perform the match.
-E, --empty Search for empty cells, i.e. filter out
any completely non-empty selection.
-N, --non-empty Search for non-empty cells, i.e. filter out
any completely empty selection.
--patterns <path> Path to a text file (use "-" for stdin), containing multiple
Expand All @@ -57,6 +70,9 @@ search options:
-s, --select <arg> Select the columns to search. See 'xan select -h'
for the full syntax.
-v, --invert-match Select only rows that did not match
-A, --all Only return a row when ALL columns from the given selection
match the desired pattern, instead of returning a row
when ANY column matches.
-f, --flag <column> If given, the command will not filter rows
but will instead flag the found rows in a new
column with given name.
Expand Down
1 change: 1 addition & 0 deletions docs/moonblade.md
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ use the operators in the previous section.
Move a source to target path. Will create necessary directories
on the way. Returns target path as a convenience.

- pjoin(string, *strings) -> string
- pathjoin(string, *strings) -> string
Join multiple paths correctly.

Expand Down
10 changes: 9 additions & 1 deletion src/cmd/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ search options:
-s, --select <arg> Select the columns to search. See 'xan select -h'
for the full syntax.
-v, --invert-match Select only rows that did not match
-A, --all Only return a row when ALL columns from the given selection
match the desired pattern, instead of returning a row
when ANY column matches.
-f, --flag <column> If given, the command will not filter rows
but will instead flag the found rows in a new
column with given name.
Expand All @@ -151,6 +154,7 @@ struct Args {
flag_no_headers: bool,
flag_delimiter: Option<Delimiter>,
flag_invert_match: bool,
flag_all: bool,
flag_ignore_case: bool,
flag_empty: bool,
flag_non_empty: bool,
Expand Down Expand Up @@ -283,7 +287,11 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
let mut i: usize = 0;

while rdr.read_byte_record(&mut record)? {
let mut is_match = sel.select(&record).any(|cell| matcher.is_match(cell));
let mut is_match = if args.flag_all {
sel.select(&record).all(|cell| matcher.is_match(cell))
} else {
sel.select(&record).any(|cell| matcher.is_match(cell))
};

if args.flag_invert_match {
is_match = !is_match;
Expand Down
22 changes: 22 additions & 0 deletions tests/test_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,3 +436,25 @@ fn search_empty() {
let expected = vec![svec!["name"], svec![""]];
assert_eq!(got, expected);
}

#[test]
fn search_all() {
let wrk = Workdir::new("search_all");

wrk.create(
"data.csv",
vec![
svec!["name", "color"],
svec!["John", "red"],
svec!["", "yellow"],
svec!["Suzy", ""],
],
);

let mut cmd = wrk.command("search");
cmd.arg("data.csv").arg("--non-empty").arg("--all");

let got: Vec<Vec<String>> = wrk.read_stdout(&mut cmd);
let expected = vec![svec!["name", "color"], svec!["John", "red"]];
assert_eq!(got, expected);
}

0 comments on commit 3dac3e9

Please sign in to comment.