Java Shell通配符标记器

2019年12月2日 15点热度 0条评论

我的Java非常生锈,我一直试图建立一个用户界面来简化shell脚本或批处理文件的执行,具体取决于它是Linus还是Win32。这些文件具有以下命名约定。

  module-verb-object-etc [args-list]
  mysql-connect-grid
  mysql-connect-rds
  mysql-dump-grid
  mysql-dump-grid-se314

最终,我希望它能够解析明确的术语,因此我可以:

标记命令(例如,以“-”分隔)并将其缩短为简化术语,例如foxpro的命令窗口或cisco的IOS(例如,“ my co gr”在unix中执行“ mysql-connect-grid”,在win32中执行* .cmd)

并且还采用IOS的样式,允许用户输入缩写命令,以便他们可以输入问号(?),并向他们提示剩余的唯一(或下一个)命令选项(例如“我的?”)。返回mysql&“ my?”返回连接或转储。对于非唯一或无法匹配的命令,Othr返回值将是“模糊的”或“未知的”。看起来似乎很琐碎,但每个文件夹中都有数百个命令,我的用户不想考虑...

我编写了一个函数,用于从目录中提取文件列表并重新调整Fileanmes数组。然后,使用下面的方法将其转换为二维数组,该方法将返回动态尺寸的潜在命令网格。

    /**********************************************************************************
     *  MAKE GRID: Parses array of filenames and 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][]; 
       for (int nRow=0; nRow<nRows; nRow++) { 
 String cFilename = strs[nRow];
                if (!cFilename.endsWith(".cmd") // just list unix files (filter for batch files)
    && cFilename.indexOf("-") > 0 ) // make sure there's a dash in the filename
    {
           String strTokens[] = tokenize(strs[nRow], "-"); // the dash is our token deliminator
           int nCols = strTokens.length; 
           if (nCols>nMaxCols) nMaxCols=nCols;
           tmpGrid[nGridRow] = new String [nCols];
           for (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;
      }

这将返回一个二维数组(如下),因此
grid[Row-N][Col-0]是一个匹配项。我只想提取不同的值,其中
row[0]
cmdToken[0] && row[1]的通配符匹配,是“ like”
cmdToken[1],以便我的用户可以拼凑一条命令,直到
"my du gr ?"返回
"ENTER, [se314]"-如果这有意义...

String[][] makeGrid:
    mysql dump grid se314
    mysql connect grid
    mysql dump grid
    mysql connect rds

我的挑战:我似乎无法理解Java中的Matcher函数。如果是SQL,它将类似于:

"SELECT DISTINCT col2 FROM cmd_Grid
   WHERE col1 LIKE 'cmdToken1%' " 

甚至更好:为每个连续列递归设置int深度标记

`SELECT DISTINCT col+str(depthmark+1) FROM cmd_Grid 
    WHERE col+str(depthmark) LIKE 'cmdMatchedTokens%' " 

直到您完全匹配为止。

我找到了一个名为joSQL的程序包,该程序我经过无奈的尝试,但似乎无法使其在Java6中正常工作。无论如何:我也希望有一个纯Java解决方案,以便所有内容都可以包含在一个类中。

也许使用扫描仪或某种方法来解析我的多维数组以获得唯一值...我知道我可能使它变得比所需的更加复杂。

朝正确方向轻轻推一下将不胜感激。

TIA

解决方案如下:

一种详尽的解决方案是构造一个hashMap,以便密钥是可能的短命令,例如“ my co gr”,而对应的值是“ mysql-connect-grid”。
因此,散列图中将存在将“ mysql-connect-grid”作为值的值。

但是,只有在可能的密钥数量有限的情况下,这才是可行的解决方案。
如果不是这种情况,则可以使用内置的字符串解析方法。

例如:

    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++;
      }
  }

此代码段应使您了解如何进行操作。不过,这里要注意一件事。 matchingsCommands数组已初始化为4行4列,这很浪费,因为匹配项会少于此。如果您需要帮助以提高效率,请告诉我。否则,这是一段有效的代码,我认为您可以执行所需的工作。