Question

Mon Java est extrêmement rouillé et je suis coincé essayer de faire une interface utilisateur qui simplifie l'exécution des scripts shell ou des fichiers batch selon que ce soit Linus ou Win32 respectivement. Les fichiers ont la convention de nommage suivante.

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

finalement, je voudrais qu'il analyser sans ambiguïté que je puisse:

  1. tokenize les commandes (par exemple, délimitées par des « - ») et raccourcissez en termes simplifiés soemthing comme la fenêtre de commande de foxpro ou IOS cisco (par exemple, « mon co gr » exécute « mysql-connect-grid » dans unix et * .cmd dans win32)
  2. et aussi dans le style de l'IOS permettent à l'utilisateur d'entrer des commandes abrégées afin qu'ils puissent saisir un point d'interrogation (?) Et il leur donnera une indication quant aux options de commande unique, restant (ou suivant) (par exemple " mon? » MySQL retourne et « renvoie mes? » Se connecter ou décharge). Les valeurs othr de retour seraient « ambigus » ou « inconnu » pour les commandes qui ne sont pas uniques ou ne pouvaient pas être apparié. Il peut sembler trivial, mais il y a plusieurs centaines de commandes dans chaque dossier et mes utilisateurs ne veulent pas penser ...

J'ai écrit une fonction pour tirer la liste des fichiers à partir d'un répertoire et retun un tableau de fileanmes. Puis je convertir en un réseau bidimensionnel 2 en utilisant la méthode ci-dessous qui renvoie une grille de taille de dynamicly de commandes possibles.

    /**********************************************************************************
     *  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;
      }

renvoie une matrice 2-D (ci-dessous), de sorte que grid[Row-N][Col-0] est une allumette. Je voudrais tirer que des valeurs distinctes où row[0] est un match de joker pour cmdToken[0] && row[1] est « comme » cmdToken[1] pour que mes utilisateurs peuvent rassembler une commande jusqu'à ce que "my du gr ?" retourne "ENTER, [se314]" - si cela fait sens ...

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

Mon défi: Je ne peux pas sembler obtenir ma tête autour de ma fonction de matcher en java. Si c'était SQL ce serait quelque chose comme:

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

ou mieux encore: la mise en récursivement un depthmark int pour chaque colonne consécutive

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

jusqu'à ce que vous avez une correspondance exacte.

J'ai trouvé un paquet appelé joSQL que j'ai essayé en désespoir de cause, mais je ne peux pas l'air de le faire fonctionner dans java6. Quoi qu'il en soit: j'espérais aussi une solution pure java pour que tout pourrait être contenu dans une seule classe ...

en utilisant peut-être scanner ou quelque chose pour analyser mon tableau des valeurs uniques pour multidimentionnelle ... Je sais que je suis sans doute ce qui en fait beaucoup plus complexe qu'il doit être.

un petit coup de pouce dans la bonne direction serait appréciée.

TIA

Était-ce utile?

La solution

Une solution exhaustive pourrait être à contruct HashMap de sorte que la clé est une commande courte possible, comme mon co gr » et la valeur correspondante est « mysql-connect-grid ». Donc, il y aurait des valeurs dans la carte de hachage qui aura « mysql-connexion réseau » comme valeur.

Mais ceci est une solution réalisable que s'il y a un nombre fini de clés possibles. Si ce n'est pas le cas, vous pouvez utiliser les fonctions intégrées dans les méthodes d'analyse de chaînes.

Par exemple:

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

Cet extrait de code devrait vous donner une idée de la façon de s'y prendre. Il y a une chose à noter ici cependant. matchingCommands array a été initialisé aux 4 lignes et 4 colonnes qui est inutile parce que les matches seront moins que cela. Laissez-moi savoir si vous avez besoin d'aide pour faire de ce plus efficace. Dans le cas contraire, c'est un morceau de travail de code qui je pense ne ce que vous voulez.

Autres conseils

Vous pouvez également regarder dans certaines structures de données plus avancées comme un ArrayList au lieu d'un tableau et en utilisant la StringTokenizer pour générer chaque commande partie à la volée.

Ce sera quelque chose comme ceci:

ArrayList<String> matchingCommands = new ArrayList<String>();

    ArrayList<String> commandList = new ArrayList<String>();
    commandList.add("mysql dump grid se314");
    commandList.add("mysql connect grid");
    commandList.add("mysql dump grid");
    commandList.add("mysql connect rds");

    String queryCommand = "my du gr ?";

    for(int i=0; i<commandList.size(); i++)
    {
        boolean matches = false;
        String command = commandList.get(i);
        StringTokenizer commandTokenizer = new StringTokenizer(command, " "); // Using space as the deliminator
        StringTokenizer queryTokenizer = new StringTokenizer(queryCommand, " "); // Using space as the deliminator

        while(commandTokenizer.hasMoreTokens())
        {
            String queryPart = queryTokenizer.nextToken();
            String commandPart = commandTokenizer.nextToken();
            if(commandPart.startsWith(queryPart) || queryPart.equals("?")){
                matches = true;
            }else{
                matches = false;
                break;
            }
        }
        if(matches){
            matchingCommands.add(command);
        }
    }
    System.out.println(matchingCommands);

Ceci assurez-vous que votre programme peut se développer de façon dynamique et il n'y a pas de gaspillage de la mémoire à cause d'objets nuls non plus.

en ce moment je en train de jouer autour de chaque analyse syntaxique chaîne_cmd (requête) pour délimiteurs espace blanc et tokenizing le tableau. Quelque chose comme:

 Scanner sCmdString = new Scanner(cInput);
 while (sCmdString.hasNext()) { 
 String cToken = sCmdString.next().toUpperCase().trim();
 System.out.println(" "+cToken+" ");
 // match cmdString[i..n] to cmdGrid
 for (int nRow=0; nRow < cmdGrid.length; nRow++) {
       for (int nCol=0; nCol < cmdGrid[nRow].length; nCol++) {
  if (cmdGrid[nRow][nCol].equalsIgnoreCase(cToken) )
     System.out.println("MATCH: "+cmdGrid[nRow][nCol]);
  else System.out.println("NO MATCH:"+cmdGrid[nRow][nCol].toUpperCase()+":"+cToken+"...");
        }
   }
   }

mais je devenais NPE avec les longueurs inégales de ligne.

J'aime votre idée d'aplatir les colonnes.

Je pense que je dois encore supprimer les doublons ... non?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top