SDDSlib
Loading...
Searching...
No Matches
sddsmselect.c File Reference

A utility program for creating SDDS data sets based on matching data. More...

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"

Go to the source code of this file.

Typedefs

typedef char * STRING_PAIR[2]
 

Enumerations

enum  option_type {
  SET_MATCH_COLUMNS , SET_EQUATE_COLUMNS , SET_NOWARNINGS , SET_INVERT ,
  SET_REUSE , SET_PIPE , SET_MAJOR_ORDER , N_OPTIONS
}
 

Functions

long rows_equate (SDDS_DATASET *SDDS1, int64_t row1, SDDS_DATASET *SDDS2, int64_t row2, long equate_columns, STRING_PAIR *equate_column)
 
int main (int argc, char **argv)
 

Variables

char * option [N_OPTIONS]
 
char * USAGE
 

Detailed Description

A utility program for creating SDDS data sets based on matching data.

This program creates an SDDS (Self Describing Data Set) file from an input dataset by selecting rows based on matching or equating data from a second dataset. It provides flexibility for data matching, inversion, and reuse of rows, and can handle both row-major and column-major data ordering.

Features:

  • Match rows in the input dataset against another dataset using specified columns.
  • Equate numerical columns for advanced row selection.
  • Options to invert selection logic and reuse rows from the second dataset.
  • Output can be formatted in row-major or column-major order.

Usage:

sddsmselect [OPTIONS] [<input1>] <input2> [<output>]

Options:

  • -pipe[=input][,output]: Use pipe for input and/or output.
  • -match=<col1>=<col2>,...: Specify columns to match between datasets.
  • -equate=<col1>=<col2>,...: Specify columns to equate between datasets.
  • -invert: Select rows with no matching rows in the second dataset.
  • -reuse[=rows|page]: Allow reuse of rows from the second dataset.
  • -majorOrder=row|column: Set the output file order.
  • -nowarnings: Suppress warning messages.

Example:

sddsmselect -match=ID=ID1 input1.sdds input2.sdds output.sdds
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday, H. Shang

Definition in file sddsmselect.c.

Typedef Documentation

◆ STRING_PAIR

typedef char* STRING_PAIR[2]

Definition at line 62 of file sddsmselect.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 51 of file sddsmselect.c.

51 {
52 SET_MATCH_COLUMNS,
53 SET_EQUATE_COLUMNS,
54 SET_NOWARNINGS,
55 SET_INVERT,
56 SET_REUSE,
57 SET_PIPE,
58 SET_MAJOR_ORDER,
59 N_OPTIONS
60};

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 107 of file sddsmselect.c.

107 {
108 SDDS_DATASET SDDS_1, SDDS_2, SDDS_output;
109 long i, i_arg, reuse, reusePage;
110 int64_t j, k, rows1, rows2, n, outputRow;
111 SCANNED_ARG *s_arg;
112 char s[200], *ptr;
113 STRING_PAIR *match_column, *equate_column;
114 long match_columns, equate_columns;
115 char *input1, *input2, *output, *match_value;
116 long tmpfile_used, retval1, retval2;
117 long *row_used, warnings, invert;
118 unsigned long pipeFlags, majorOrderFlag;
119 short columnMajorOrder = -1;
120
122 argc = scanargs(&s_arg, argc, argv);
123 if (argc < 3)
124 bomb(NULL, USAGE);
125
126 input1 = input2 = output = NULL;
127 match_column = equate_column = NULL;
128 match_columns = equate_columns = reuse = reusePage = invert = 0;
129 tmpfile_used = 0;
130 warnings = 1;
131 pipeFlags = 0;
132
133 for (i_arg = 1; i_arg < argc; i_arg++) {
134 if (s_arg[i_arg].arg_type == OPTION) {
135 delete_chars(s_arg[i_arg].list[0], "_");
136 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
137 case SET_MAJOR_ORDER:
138 majorOrderFlag = 0;
139 s_arg[i_arg].n_items--;
140 if (s_arg[i_arg].n_items > 0 &&
141 (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items,
142 0, "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
143 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
144 SDDS_Bomb("Invalid -majorOrder syntax or values.");
145 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
146 columnMajorOrder = 1;
147 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
148 columnMajorOrder = 0;
149 break;
150 case SET_MATCH_COLUMNS:
151 if (s_arg[i_arg].n_items < 2)
152 SDDS_Bomb("Invalid -match syntax.");
153 match_column = trealloc(match_column, sizeof(*match_column) * (match_columns + s_arg[i_arg].n_items - 1));
154 for (i = 1; i < s_arg[i_arg].n_items; i++) {
155 if ((ptr = strchr(s_arg[i_arg].list[i], '=')))
156 *ptr++ = 0;
157 else
158 ptr = s_arg[i_arg].list[i];
159 match_column[i - 1 + match_columns][0] = s_arg[i_arg].list[i];
160 match_column[i - 1 + match_columns][1] = ptr;
161 }
162 match_columns += s_arg[i_arg].n_items - 1;
163 break;
164 case SET_EQUATE_COLUMNS:
165 if (s_arg[i_arg].n_items < 2)
166 SDDS_Bomb("Invalid -equate syntax.");
167 equate_column = trealloc(equate_column, sizeof(*equate_column) * (equate_columns + s_arg[i_arg].n_items - 1));
168 for (i = 1; i < s_arg[i_arg].n_items; i++) {
169 if ((ptr = strchr(s_arg[i_arg].list[i], '=')))
170 *ptr++ = 0;
171 else
172 ptr = s_arg[i_arg].list[i];
173 equate_column[i - 1 + equate_columns][0] = s_arg[i_arg].list[i];
174 equate_column[i - 1 + equate_columns][1] = ptr;
175 }
176 equate_columns += s_arg[i_arg].n_items - 1;
177 break;
178 case SET_REUSE:
179 if (s_arg[i_arg].n_items == 1)
180 reuse = 1;
181 else {
182 char *reuseOptions[2] = {"rows", "page"};
183 for (i = 1; i < s_arg[i_arg].n_items; i++) {
184 switch (match_string(s_arg[i_arg].list[i], reuseOptions, 2, 0)) {
185 case 0:
186 reuse = 1;
187 break;
188 case 1:
189 reusePage = 1;
190 break;
191 default:
192 SDDS_Bomb("Unknown reuse keyword.");
193 break;
194 }
195 }
196 }
197 break;
198 case SET_NOWARNINGS:
199 warnings = 0;
200 break;
201 case SET_INVERT:
202 invert = 1;
203 break;
204 case SET_PIPE:
205 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
206 SDDS_Bomb("Invalid -pipe syntax.");
207 break;
208 default:
209 fprintf(stderr, "Error: Unknown option: %s\n", s_arg[i_arg].list[0]);
210 bomb(NULL, USAGE);
211 break;
212 }
213 } else {
214 if (input1 == NULL)
215 input1 = s_arg[i_arg].list[0];
216 else if (input2 == NULL)
217 input2 = s_arg[i_arg].list[0];
218 else if (output == NULL)
219 output = s_arg[i_arg].list[0];
220 else
221 SDDS_Bomb("Too many filenames provided.");
222 }
223 }
224
225 if (pipeFlags & USE_STDIN && input1) {
226 if (output)
227 SDDS_Bomb("Too many filenames with -pipe option.");
228 output = input2;
229 input2 = input1;
230 input1 = NULL;
231 }
232 processFilenames("sddsmselect", &input1, &output, pipeFlags, !warnings, &tmpfile_used);
233 if (!input2)
234 SDDS_Bomb("Second input file not specified.");
235
236 if (!match_columns && !equate_columns)
237 SDDS_Bomb("Either -match or -equate must be specified.");
238
239 if (!SDDS_InitializeInput(&SDDS_1, input1)) {
240 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
241 exit(EXIT_FAILURE);
242 }
243 if (!SDDS_InitializeInput(&SDDS_2, input2)) {
244 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
245 exit(EXIT_FAILURE);
246 }
247
248 for (i = 0; i < match_columns; i++) {
249 if ((j = SDDS_GetColumnIndex(&SDDS_1, match_column[i][0])) < 0 ||
250 SDDS_GetColumnType(&SDDS_1, j) != SDDS_STRING) {
251 sprintf(s, "Error: Column '%s' not found or not of string type in file '%s'.",
252 match_column[i][0], input1 ? input1 : "stdin");
253 SDDS_SetError(s);
254 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
255 }
256 if ((j = SDDS_GetColumnIndex(&SDDS_2, match_column[i][1])) < 0 ||
257 SDDS_GetColumnType(&SDDS_2, j) != SDDS_STRING) {
258 sprintf(s, "Error: Column '%s' not found or not of string type in file '%s'.",
259 match_column[i][1], input2);
260 SDDS_SetError(s);
261 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
262 }
263 }
264 for (i = 0; i < equate_columns; i++) {
265 if ((j = SDDS_GetColumnIndex(&SDDS_1, equate_column[i][0])) < 0 ||
267 sprintf(s, "Error: Column '%s' not found or not of numeric type in file '%s'.",
268 equate_column[i][0], input1 ? input1 : "stdin");
269 SDDS_SetError(s);
270 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
271 }
272 if ((j = SDDS_GetColumnIndex(&SDDS_2, equate_column[i][1])) < 0 ||
274 sprintf(s, "Error: Column '%s' not found or not of numeric type in file '%s'.",
275 equate_column[i][1], input2);
276 SDDS_SetError(s);
277 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
278 }
279 }
280
281 if (output && (pipeFlags & USE_STDOUT))
282 SDDS_Bomb("Too many filenames with -pipe option.");
283 if (!output && !(pipeFlags & USE_STDOUT)) {
284 if (warnings)
285 fprintf(stderr, "Warning: Existing file '%s' will be replaced.\n", input1 ? input1 : "stdin");
286 tmpfile_used = 1;
287 cp_str(&output, tmpname(NULL));
288 }
289 if (!SDDS_InitializeCopy(&SDDS_output, &SDDS_1, output, "w")) {
290 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
291 exit(EXIT_FAILURE);
292 }
293 if (columnMajorOrder != -1)
294 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
295 else
296 SDDS_output.layout.data_mode.column_major = SDDS_1.layout.data_mode.column_major;
297 if (!SDDS_WriteLayout(&SDDS_output))
298 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
299
300 row_used = NULL;
301 while ((retval1 = SDDS_ReadPage(&SDDS_1)) > 0) {
302 if (!reusePage) {
303 if ((retval2 = SDDS_ReadPage(&SDDS_2)) <= 0) {
304 if (warnings)
305 fprintf(stderr, "Warning: <input2> ends before <input1>.\n");
306 if (invert) {
307 /* Nothing to match, so everything would normally be thrown out */
308 if (!SDDS_CopyPage(&SDDS_output, &SDDS_1) ||
309 !SDDS_WritePage(&SDDS_output))
310 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
311 continue;
312 } else
313 /* Nothing to match, so everything thrown out */
314 break;
315 }
316 } else {
317 if (retval1 == 1 && (retval2 = SDDS_ReadPage(&SDDS_2)) <= 0)
318 SDDS_Bomb("<input2> has no data.");
319 SDDS_SetRowFlags(&SDDS_2, 1);
320 }
321 SDDS_SetRowFlags(&SDDS_1, 1);
322 rows1 = SDDS_CountRowsOfInterest(&SDDS_1);
323 if ((rows2 = SDDS_CountRowsOfInterest(&SDDS_2))) {
324 row_used = SDDS_Realloc(row_used, sizeof(*row_used) * rows2);
325 SDDS_ZeroMemory(row_used, rows2 * sizeof(*row_used));
326 }
327 if (!SDDS_StartPage(&SDDS_output, rows1)) {
328 SDDS_SetError("Problem starting output page.");
329 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
330 }
331 if (!SDDS_CopyParameters(&SDDS_output, &SDDS_1) ||
332 !SDDS_CopyArrays(&SDDS_output, &SDDS_1)) {
333 SDDS_SetError("Problem copying parameter or array data from first input file.");
334 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
335 }
336 outputRow = 0;
337 for (j = 0; j < rows1; j++) {
338 /* Set up to match all rows of file 2 to row j of file 1 */
339 SDDS_SetRowFlags(&SDDS_2, 1);
340 for (i = 0; i < match_columns; i++) {
341 if (!SDDS_GetValue(&SDDS_1, match_column[i][0], j, &match_value)) {
342 sprintf(s, "Problem getting column '%s' from file '%s'.",
343 match_column[i][0], input1 ? input1 : "stdin");
344 SDDS_SetError(s);
345 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
346 }
347 if (SDDS_MatchRowsOfInterest(&SDDS_2, match_column[i][1], match_value, SDDS_AND) < 0) {
348 sprintf(s, "Problem setting rows of interest for column '%s'.",
349 match_column[i][1]);
350 SDDS_SetError(s);
351 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
352 }
353 }
354 n = SDDS_CountRowsOfInterest(&SDDS_2);
355 if ((!n && !invert) || (n && invert))
356 /* No match in file2 for row j of file1, or unwanted match found--so don't copy it */
357 continue;
358 for (k = 0; k < rows2; k++) {
359 if (SDDS_GetRowFlag(&SDDS_2, k) < 0)
360 /* Test if row k of file2 passed string-matches. If not, go to next row */
361 continue;
362 /* If row k of file2 is not already used, then test it for a match to row j of file1.
363 If no -equate options were given, this test is always true.
364 */
365 if (!row_used[k]) {
366 long equal;
367 equal = rows_equate(&SDDS_1, j, &SDDS_2, k, equate_columns, equate_column);
368 if ((equal && !invert) || (!equal && invert)) {
369 row_used[k] = reuse ? 0 : 1;
370 break;
371 }
372 }
373 }
374 if ((k == rows2 && !invert) || (k != rows2 && invert))
375 /* No match in file2 for row j of file1, or unwanted match found--so don't copy it */
376 continue;
377 if (!SDDS_CopyRowDirect(&SDDS_output, outputRow, &SDDS_1, j)) {
378 sprintf(s, "Problem copying to row %" PRId64 " of output from row %" PRId64 " of data set 1.",
379 outputRow, j);
380 SDDS_SetError(s);
381 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
382 }
383 outputRow++;
384 }
385 if (!SDDS_WritePage(&SDDS_output)) {
386 SDDS_SetError("Problem writing data to output file.");
387 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
388 }
389 }
390
391 if (!SDDS_Terminate(&SDDS_1) ||
392 !SDDS_Terminate(&SDDS_2) ||
393 !SDDS_Terminate(&SDDS_output)) {
394 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
395 exit(EXIT_FAILURE);
396 }
397
398 if (tmpfile_used && !replaceFileAndBackUp(input1, output))
399 exit(EXIT_FAILURE);
400
401 return EXIT_SUCCESS;
402}
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:286
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_CopyRowDirect(SDDS_DATASET *SDDS_target, int64_t target_row, SDDS_DATASET *SDDS_source, int64_t source_row)
Definition SDDS_copy.c:834
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_CopyArrays(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:334
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
int32_t SDDS_GetRowFlag(SDDS_DATASET *SDDS_dataset, int64_t row)
Retrieves the acceptance flag of a specific row in the current data table.
int32_t SDDS_SetRowFlags(SDDS_DATASET *SDDS_dataset, int32_t row_flag_value)
Sets the acceptance flags for all rows in the current data table of a data set.
int64_t SDDS_MatchRowsOfInterest(SDDS_DATASET *SDDS_dataset, char *selection_column, char *label_to_match, int32_t logic)
Matches and marks rows of interest in an SDDS dataset based on label matching.
void * SDDS_GetValue(SDDS_DATASET *SDDS_dataset, char *column_name, int64_t srow_index, void *memory)
Retrieves the value from a specified column and selected row, optionally storing it in provided memor...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
int32_t SDDS_ZeroMemory(void *mem, int64_t n_bytes)
Sets a block of memory to zero.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Definition SDDStypes.h:138
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
Definition replacefile.c:75
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.
char * tmpname(char *s)
Supplies a unique temporary filename.
Definition tmpname.c:34

◆ rows_equate()

long rows_equate ( SDDS_DATASET * SDDS1,
int64_t row1,
SDDS_DATASET * SDDS2,
int64_t row2,
long equate_columns,
STRING_PAIR * equate_column )

Definition at line 404 of file sddsmselect.c.

404 {
405 char *data1, *data2;
406 long index1, index2, size, type, i;
407 char s[SDDS_MAXLINE];
408 index2 = 0;
409 for (i = 0; i < equate_columns; i++) {
410 if ((index1 = SDDS_GetColumnIndex(SDDS1, equate_column[i][0])) < 0 ||
411 (index2 = SDDS_GetColumnIndex(SDDS2, equate_column[i][1])) < 0) {
412 SDDS_SetError("Problem equating rows.");
413 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
414 }
415 if ((type = SDDS_GetColumnType(SDDS1, index1)) != SDDS_GetColumnType(SDDS2, index2)) {
416 sprintf(s, "Problem equating rows--types don't match for columns '%s' and '%s'.",
417 equate_column[i][0], equate_column[i][1]);
418 SDDS_SetError(s);
419 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
420 }
421 size = SDDS_GetTypeSize(type);
422 data1 = (char *)SDDS1->data[index1] + size * row1;
423 data2 = (char *)SDDS2->data[index2] + size * row2;
424 if (memcmp(data1, data2, size) != 0)
425 return 0;
426 }
427 return 1;
428}
int32_t SDDS_GetTypeSize(int32_t type)
Retrieves the size in bytes of a specified SDDS data type.

Variable Documentation

◆ option

char* option[N_OPTIONS]
Initial value:
= {
"match",
"equate",
"nowarnings",
"invert",
"reuse",
"pipe",
"majorOrder"
}

Definition at line 66 of file sddsmselect.c.

66 {
67 "match",
68 "equate",
69 "nowarnings",
70 "invert",
71 "reuse",
72 "pipe",
73 "majorOrder"
74};

◆ USAGE

char* USAGE
Initial value:
=
"Usage: sddsmselect [OPTIONS] [<input1>] <input2> [<output>]\n"
"\n"
"Options:\n"
" -pipe[=input][,output] Use pipe for input and/or output.\n"
" -match=<col1>=<col2>,... Specify columns to match between input1 and input2.\n"
" -equate=<col1>=<col2>,... Specify columns to equate between input1 and input2.\n"
" -invert Select rows with no matching rows in input2.\n"
" -reuse[=rows|page] Allow reuse of rows from input2.\n"
" -majorOrder=row|column Set output file order to row or column major.\n"
" -nowarnings Suppress warning messages.\n"
"\n"
"Description:\n"
" sddsmselect selects data from <input1> to write to <output>\n"
" based on the presence or absence of matching data in <input2>.\n"
" If <output> is not specified, <input1> is replaced.\n"
"\n"
" -match Specifies names of columns to match between <input1> and\n"
" <input2> for selection and placement of data.\n"
" -equate Specifies names of columns to equate between <input1> and\n"
" <input2> for selection and placement of data.\n"
" -reuse Allows rows of <input2> to be reused, i.e., matched with\n"
" multiple rows of <input1>.\n"
" Use -reuse=page to restrict to the first page of <input2>.\n"
" -invert Select rows from <input1> that have no matching rows in <input2>.\n"
" -majorOrder Set the output file to use row or column major order.\n"
" -nowarnings Do not print warning messages.\n"
"\n"
"Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n"

Definition at line 77 of file sddsmselect.c.