2016-11-08 10 views
0

に "LS -v" シェルを実装する方法を、私はls -v /tmp/chk GETを実行します。例えばJavaの

ar1 ar20 ar100 pr1 pr20 pr100 

を私は次のGroovyコードを使用する場合:

new File("/tmp/chk").listFiles().sort().each { 
    println it.name 
} 

を結果は次のとおりです。

ar1 
ar100 
ar20 
pr1 
pr100 
pr20 

実装方法ls -vアルゴリズムは、javaまたはgroovyで同じ順序を取得する

+1

は 'ソートを(削除)' Groovy'コード 'で – Saravana

+0

を使うと自然な順序](https://github.com/:あなたのファイルの内容を持つディレクトリで、私は次のような結果を得る上でそのグルーヴィースクリプトpaour/natorder)コンパレータ、おそらく。 –

答えて

0

コードに続いて、私はそのコンテンツを含むディレクトリにls -vを実行するとうーん

public class NaturalOrderComparator implements Comparator { 
    int compareRight(String a, String b) { 
     int bias = 0; 
     int ia = 0; 
     int ib = 0; 

     // The longest run of digits wins. That aside, the greatest 
     // value wins, but we can't know that it will until we've scanned 
     // both numbers to know that they have the same magnitude, so we 
     // remember it in BIAS. 
     for (; ; ia++, ib++) { 
      char ca = charAt(a, ia); 
      char cb = charAt(b, ib); 

      if (!Character.isDigit(ca) && !Character.isDigit(cb)) { 
       return bias; 
      } else if (!Character.isDigit(ca)) { 
       return -1; 
      } else if (!Character.isDigit(cb)) { 
       return +1; 
      } else if (ca < cb) { 
       if (bias == 0) { 
        bias = -1; 
       } 
      } else if (ca > cb) { 
       if (bias == 0) 
        bias = +1; 
      } else if (ca == 0 && cb == 0) { 
       return bias; 
      } 
     } 
    } 

    public int compare(Object o1, Object o2) { 
     String a = o1.toString(); 
     String b = o2.toString(); 

     int ia = 0, ib = 0; 
     int nza = 0, nzb = 0; 
     char ca, cb; 
     int result; 

     while (true) { 
      // only count the number of zeroes leading the last number compared 
      nza = nzb = 0; 

      ca = charAt(a, ia); 
      cb = charAt(b, ib); 

      // skip over leading spaces or zeros 
      while (Character.isSpaceChar(ca) || ca == '0') { 
       if (ca == '0') { 
        nza++; 
       } else { 
        // only count consecutive zeroes 
        nza = 0; 
       } 

       ca = charAt(a, ++ia); 
      } 

      while (Character.isSpaceChar(cb) || cb == '0') { 
       if (cb == '0') { 
        nzb++; 
       } else { 
        // only count consecutive zeroes 
        nzb = 0; 
       } 

       cb = charAt(b, ++ib); 
      } 

      // process run of digits 
      if (Character.isDigit(ca) && Character.isDigit(cb)) { 
       if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0) { 
        return result; 
       } 
      } 

      if (ca == 0 && cb == 0) { 
       // The strings compare the same. Perhaps the caller 
       // will want to call strcmp to break the tie. 
       return nza - nzb; 
      } 

      if (ca < cb) { 
       return -1; 
      } else if (ca > cb) { 
       return +1; 
      } 

      ++ia; 
      ++ib; 
     } 
    } 

    static char charAt(String s, int i) { 
     if (i >= s.length()) { 
      return 0; 
     } else { 
      return s.charAt(i); 
     } 
    } 

    public static void main(String[] args) { 
     String[] strings = new String[]{"1-2", "1-02", "1-20", "10-20", "fred", "jane", "pic01", 
       "pic2", "pic02", "pic02a", "pic3", "pic4", "pic 4 else", "pic 5", "pic05", "pic 5", 
       "pic 5 something", "pic 6", "pic 7", "pic100", "pic100a", "pic120", "pic121", 
       "pic02000", "tom", "x2-g8", "x2-y7", "x2-y08", "x8-y8"}; 

     List orig = Arrays.asList(strings); 

     System.out.println("Original: " + orig); 

     List scrambled = Arrays.asList(strings); 
     Collections.shuffle(scrambled); 

     System.out.println("Scrambled: " + scrambled); 

     Collections.sort(scrambled, new NaturalOrderComparator()); 

     System.out.println("Sorted: " + scrambled); 
    } 
} 
0

あなたは実際にプロセスビルダを見るべきです。それは本当にこの種のもののために作られています。

ProcessBuilder processBuilder = new ProcessBuilder("bash", "", "ls -v"); 
Process p = pb.start(); 
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); 
String readline; 
List<String> files = new ArrayList<String>(); 

while ((readline = reader.readLine()) != null) { 
    files.add(readline); 
} 
+0

私はJavaを使用してこのアルゴリズムを実装することを願っています – asullaherc

+0

確かに@asullaherc –

0

英数字のソートを実装、私が取得:

ar1 ar100 ar20 pr1 pr100 pr20 

は、だから私はYMMVを推測します。使用

def parseWord(String word) { 
    def (isLex, list, current) = [true, [], ''] 
    word.each { c -> 
     if (c in ('0'..'9') != isLex) { 
      current += c 
     } else { 
      list << (isLex ? current : (current as int)) 
      isLex = !isLex 
      current = c as String 
     } 
    } 
    list << (isLex ? current : (current as int)) 
} 

new File("/tmp/chk").listFiles().sort{ a, b -> 
    def aa = parseWord(a.name) 
    def bb = parseWord(b.name) 
    ([aa, bb].transpose().findResult { it[0]<=>it[1] ?: null }) ?: 0 
}.each { 
    println it.name 
} 

:あなたは辞書順ソートファイル名の非数値部分を持つように求めている、とソート数値ファイル名の数字の部分を持っている場合しかし、あなたはこのような何かを試みることができます

ar1 
ar20 
ar100 
pr1 
pr20 
pr100 
+0

この解決策に関するすべての考え@asullaherc?それはあなたが望むことをしますか? – BalRog