exec - Java Shell wildcard tokenizer -
my java extremely rusty , i'm stuck trying make user interface simplifies execution of shell scripts or batch files depending on whether it's linus or win32 respectively. files have following naming convention.
module-verb-object-etc [args-list] mysql-connect-grid mysql-connect-rds mysql-dump-grid mysql-dump-grid-se314
ultimately parse unambiguous terms can:
- tokenize commands (e.g delimited "-") & shorten them simplified terms soemthing foxpro's command window or cisco's ios (eg "my co gr" executes "mysql-connect-grid" in unix , *.cmd in win32)
- and in style of ios allow user enter abbreviated commands can type in question mark (?) , give them hint unique remaining (or next) command options (e.g. "my?" returns mysql & "my ?" returns connect, or dump). othr return values "ambiguous" or "unknown" commands not unique or not matched. may seem trivial there many hundreds of commands in each folder , users don't want think...
i wrote function pull list of files directory & retun array of fileanmes. convert 2 dimensional array using method below returns dynamicly sized grid of potential commands.
/********************************************************************************** * make grid: parses array of filenames , tokenizes aws cmds. * @param strs array of filenames **********************************************************************************/ public static string [][] makegrid(string strs[], boolean bprint) { string tmpgrid[][]; int nmaxcols = 0; int nrows = uniquecount(strs); int ngridrow = 0; tmpgrid = new string [nrows][]; (int nrow=0; nrow<nrows; nrow++) { string cfilename = strs[nrow]; if (!cfilename.endswith(".cmd") // list unix files (filter batch files) && cfilename.indexof("-") > 0 ) // make sure there's dash in filename { string strtokens[] = tokenize(strs[nrow], "-"); // dash our token deliminator int ncols = strtokens.length; if (ncols>nmaxcols) nmaxcols=ncols; tmpgrid[ngridrow] = new string [ncols]; (int ncol=0; ncol<ncols; ncol++) { tmpgrid[ngridrow][ncol] = strtokens[ncol]; if (bprint) system.out.print(" "+tmpgrid[ngridrow][ncol]); } ngridrow++; if (bprint) system.out.println(""); } //end-if } string[][] cmdgrid = new string[ngridrow][nmaxcols]; system.arraycopy(tmpgrid, 0, cmdgrid, 0, ngridrow); // removes null rows (&npes!) return cmdgrid; }
this returns 2-d array (below), grid[row-n][col-0]
match. i'd pull distinct values row[0]
wildcard match cmdtoken[0] && row[1]
"like" cmdtoken[1]
users can piece command until "my du gr ?"
returns "enter, [se314]"
- if makes sense...
string[][] makegrid: mysql dump grid se314 mysql connect grid mysql dump grid mysql connect rds
my challenge: cant seem head around matcher function in java. if sql like:
"select distinct col2 cmd_grid col1 'cmdtoken1%' "
or better: recursively setting int depthmark each consecutive column
`select distinct col+str(depthmark+1) cmd_grid col+str(depthmark) 'cmdmatchedtokens%' "
until have exact match.
i found package called josql tried out of desperation cant seem work in java6. anyway: hoping pure java solution contained in single class...
maybe using scanner or parse multidimentional array unique values... know i'm making way more complex needs be.
a gentle nudge in right direction appreciated.
tia
one exhaustive solution contruct hashmap key possible short command 'my co gr" , corresponding value "mysql-connect-grid". there values in hash map have "mysql-connect-grid" value.
but feasible solution if there finite number of possible keys. if that's not case, can use built in string parsing methods.
for example:
string[][] makegrid = new string[][]{{"mysql", "dump", "grid", "se314"}, {"mysql", "connect", "grid", ""}, {"mysql", "dump", "grid", ""}, {"mysql", "connect", "rds", ""} }; string[] query2 = new string[]{"my", "du", "gr"}; string[][] matchingcommands = new string[4][4]; int resultsize = 0; for(int i=0; i<makegrid.length; i++) { string[] commandcolumn = makegrid[i]; boolean matches = false; for(int cnt=0; cnt<commandcolumn.length; cnt++) { string commandpart = commandcolumn[cnt]; if(cnt < query2.length){ string querypart = query2[cnt]; if(commandpart.startswith(querypart) || querypart.equals("?")){ matches = true; }else{ matches = false; break; } } } if(matches){ matchingcommands[resultsize] = commandcolumn; resultsize++; } }
this code snippet should give idea of how go it. there 1 thing note here though. matchingcommands array has been initialized 4 rows , 4 columns wasteful because matches lesser that. let me know if need making more efficient. otherwise, working piece of code think want.
Comments
Post a Comment